amitbhatt6075 commited on
Commit
fb11997
Β·
1 Parent(s): c6cf010

fix: Definitive fix for model initialization order

Browse files
Files changed (1) hide show
  1. api/main.py +26 -87
api/main.py CHANGED
@@ -48,13 +48,9 @@ MODEL_REPO = "TheBloke/TinyLlama-1.1B-Chat-v1.0-GGUF"
48
  MODEL_FILENAME = "tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf"
49
  MODEL_SAVE_DIRECTORY = os.path.join(os.environ.get("WRITABLE_DIR", "/data"), "llm_model")
50
  LLAMA_MODEL_PATH = os.path.join(MODEL_SAVE_DIRECTORY, MODEL_FILENAME)
51
-
52
- EMBEDDING_MODEL_NAME = 'sentence-transformers/all-MiniLM-L6-v2'
53
- EMBEDDING_MODEL_PATH = os.path.join(ROOT_DIR, 'embedding_model')
54
  DB_PATH = os.path.join(os.environ.get("WRITABLE_DIR", "/tmp"), "vector_db_persistent")
55
 
56
- FINAL_EMBEDDING_PATH = EMBEDDING_MODEL_PATH if os.path.exists(EMBEDDING_MODEL_PATH) else EMBEDDING_MODEL_NAME
57
-
58
  _llm_instance: Optional[Llama] = None
59
  _vector_store: Optional[Any] = None
60
  _ai_strategist: Optional[AIStrategist] = None
@@ -502,100 +498,43 @@ app = FastAPI(title="Reachify AI Service (Deploy-Ready)", version="11.0.0")
502
 
503
  @app.on_event("startup")
504
  def startup_event():
505
- # Make sure we can modify the global variables
506
- global _llm_instance, _creative_director, _support_agent, _ai_strategist, _vector_store, \
507
- _budget_predictor, _influencer_matcher, _performance_predictor, _payout_forecaster, \
508
- _earnings_optimizer, _earnings_encoder, _likes_predictor, _comments_predictor, \
509
- _revenue_forecaster, _performance_scorer
510
 
511
- # --- STEP 1: DOWNLOAD AND LOAD THE LLM MODEL ---
512
  print("--- πŸš€ AI Service Starting Up... ---")
 
 
513
  try:
514
- # Create the directory where the model will be saved if it doesn't exist
515
  os.makedirs(MODEL_SAVE_DIRECTORY, exist_ok=True)
516
-
517
- # Check if the model file already exists before trying to download it
518
  if not os.path.exists(LLAMA_MODEL_PATH):
519
- print(f" - LLM model not found locally. Downloading '{MODEL_FILENAME}'...")
520
- # This function downloads the file from the Hub to the specified directory
521
- hf_hub_download(
522
- repo_id=MODEL_REPO,
523
- filename=MODEL_FILENAME,
524
- local_dir=MODEL_SAVE_DIRECTORY,
525
- local_dir_use_symlinks=False # Important for container environments
526
- )
527
- print(" - βœ… Model downloaded successfully.")
528
- else:
529
- print(f" - LLM model found locally at {LLAMA_MODEL_PATH}. Skipping download.")
530
 
531
- # Now that the file is guaranteed to be there, load it into memory
532
- print(" - Loading Llama LLM into memory...")
533
- _llm_instance = Llama(model_path=LLAMA_MODEL_PATH, n_gpu_layers=0, n_ctx=2048, verbose=False, use_mmap=False)
534
- print(" - βœ… LLM Loaded successfully.")
535
 
536
  except Exception as e:
537
- # If anything in this block fails, the LLM is not usable.
538
- print(f" - ❌ FATAL ERROR: Could not download or load the LLM model. LLM-dependent features will be disabled.")
539
- traceback.print_exc()
540
- _llm_instance = None # Ensure the global variable is None
541
-
542
- # --- STEP 2: INITIALIZE ALL AI COMPONENTS THAT NEED THE LLM ---
543
- # This part only runs if the LLM was loaded successfully (_llm_instance is not None)
544
- if _llm_instance:
545
- try:
546
- print(" - Initializing AI components...")
547
- _creative_director = CreativeDirector(llm_instance=_llm_instance)
548
-
549
- if VectorStore:
550
- _vector_store = VectorStore()
551
- print(" - RAG Engine Ready.")
552
-
553
- _ai_strategist = AIStrategist(llm_instance=_llm_instance, store=_vector_store)
554
- _support_agent = SupportAgent(llm_instance=_llm_instance, embedding_path=EMBEDDING_MODEL_PATH, db_path=DB_PATH)
555
-
556
- print(" - βœ… Core AI components (Director, Strategist, Agent) are online.")
557
 
558
- except Exception as e:
559
- print(f" - ❌ FAILED to initialize core AI components: {e}")
560
- traceback.print_exc()
561
- else:
562
- print(" - ⚠️ SKIPPING initialization of LLM-dependent components because LLM failed to load.")
563
-
564
- # --- STEP 3: LOAD ALL OTHER MODELS (These don't depend on the LLM) ---
565
- print(" - Loading ML models from joblib files...")
566
- model_paths = {
567
- 'budget': ('_budget_predictor', 'budget_predictor_v1.joblib'),
568
- 'matcher': ('_influencer_matcher', 'influencer_matcher_v1.joblib'),
569
- 'performance': ('_performance_predictor', 'performance_predictor_v1.joblib'),
570
- 'payout': ('_payout_forecaster', 'payout_forecaster_v1.joblib'),
571
- 'earnings': ('_earnings_optimizer', 'earnings_model.joblib'),
572
- 'earnings_encoder': ('_earnings_encoder', 'earnings_encoder.joblib'),
573
- 'likes_predictor': ('_likes_predictor', 'likes_predictor_v1.joblib'),
574
- 'comments_predictor': ('_comments_predictor', 'comments_predictor_v1.joblib'),
575
- 'revenue_forecaster': ('_revenue_forecaster', 'revenue_forecaster_v1.joblib'),
576
- 'performance_scorer': ('_performance_scorer', 'performance_scorer_v1.joblib'),
577
- }
578
- for name, (var, file) in model_paths.items():
579
- path = os.path.join(MODELS_DIR, file)
580
- try:
581
- globals()[var] = joblib.load(path)
582
- print(f" - Loaded {name} model.")
583
- except FileNotFoundError:
584
- globals()[var] = None
585
- print(f" - ⚠️ WARNING: Model '{name}' not found at {path}. Endpoint will be disabled.")
586
-
587
- print(" - Initializing Text Embedding Model...")
588
- load_embedding_model(EMBEDDING_MODEL_PATH)
589
 
590
  print("\n--- βœ… AI Service startup sequence finished! ---")
591
 
592
- @app.get("/", summary="Health Check")
593
- def read_root():
594
- # We add a check here to see if the LLM loaded successfully during startup.
595
- # This helps with debugging on the live server.
596
- if _llm_instance is None:
597
- return {"status": "AI Service is running, but the Core LLM FAILED to load. Check logs."}
598
- return {"status": "AI Service is running and all models are loaded."}
599
 
600
  def _cleanup_llm_response(data: dict) -> dict:
601
  """A robust helper to clean common messy JSON outputs from smaller LLMs."""
 
48
  MODEL_FILENAME = "tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf"
49
  MODEL_SAVE_DIRECTORY = os.path.join(os.environ.get("WRITABLE_DIR", "/data"), "llm_model")
50
  LLAMA_MODEL_PATH = os.path.join(MODEL_SAVE_DIRECTORY, MODEL_FILENAME)
51
+ EMBEDDING_MODEL_PATH = os.path.join(ROOT_DIR, 'embedding_model') # This path is correct
 
 
52
  DB_PATH = os.path.join(os.environ.get("WRITABLE_DIR", "/tmp"), "vector_db_persistent")
53
 
 
 
54
  _llm_instance: Optional[Llama] = None
55
  _vector_store: Optional[Any] = None
56
  _ai_strategist: Optional[AIStrategist] = None
 
498
 
499
  @app.on_event("startup")
500
  def startup_event():
501
+ global _llm_instance, _creative_director, _ai_strategist, _support_agent
 
 
 
 
502
 
 
503
  print("--- πŸš€ AI Service Starting Up... ---")
504
+
505
+ # STEP 1: DOWNLOAD AND LOAD THE LLM
506
  try:
 
507
  os.makedirs(MODEL_SAVE_DIRECTORY, exist_ok=True)
 
 
508
  if not os.path.exists(LLAMA_MODEL_PATH):
509
+ print(f" - Downloading LLM: {MODEL_FILENAME}...")
510
+ hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILENAME, local_dir=MODEL_SAVE_DIRECTORY)
511
+ print(" - βœ… Download complete.")
 
 
 
 
 
 
 
 
512
 
513
+ print(" - Loading LLM into memory...")
514
+ _llm_instance = Llama(model_path=LLAMA_MODEL_PATH, n_gpu_layers=0, n_ctx=2048, verbose=False)
515
+ print(" - βœ… LLM Loaded.")
 
516
 
517
  except Exception as e:
518
+ print(f" - ❌ FATAL ERROR: Could not load LLM. Error: {e}")
519
+ return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
520
 
521
+ # STEP 2: INITIALIZE AI COMPONENTS that need the LLM
522
+ print(" - Initializing AI components...")
523
+ try:
524
+ _creative_director = CreativeDirector(llm_instance=_llm_instance)
525
+ _ai_strategist = AIStrategist(llm_instance=_llm_instance, store=None) # Assuming store is optional
526
+ _support_agent = SupportAgent(llm_instance=_llm_instance, embedding_path=EMBEDDING_MODEL_PATH, db_path=DB_PATH)
527
+ except Exception as e:
528
+ print(f" - ❌ Error initializing AI agents: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
 
530
  print("\n--- βœ… AI Service startup sequence finished! ---")
531
 
532
+ @app.get("/")
533
+ def health_check():
534
+ if _llm_instance:
535
+ return {"status": "AI Service is Running"}
536
+ else:
537
+ return {"status": "AI Service is in a degraded state: Core LLM failed to load."}
 
538
 
539
  def _cleanup_llm_response(data: dict) -> dict:
540
  """A robust helper to clean common messy JSON outputs from smaller LLMs."""