77
88import httpx
99import torch
10-
11- from app .core .config import settings
1210from app .constants import InferenceStatus
11+ from app .core .config import settings
1312from app .core .database import SessionLocal
1413from app .models .job import Job
1514from app .schemas .job import ChatMessage
2827
2928# ── Mock implementations ──────────────────────────────────────
3029
30+
3131def deploy_mock (job_id : str ) -> None :
3232 update_job (job_id , inference_status = InferenceStatus .DEPLOYING )
3333 time .sleep (1 )
@@ -36,12 +36,14 @@ def deploy_mock(job_id: str) -> None:
3636
3737# ── OneComp implementations (CPU / MPS) ──────────────────────
3838
39+
3940def deploy_onecomp (job_id : str , model_name : str , model_dir : str ) -> None :
4041 """Load quantized model directly from local path."""
4142 update_job (job_id , inference_status = InferenceStatus .DEPLOYING )
4243
4344 try :
4445 from onecomp import load_quantized_model
46+
4547 model , tokenizer = load_quantized_model (model_dir )
4648
4749 if settings .device == "mps" and torch .backends .mps .is_available ():
@@ -87,7 +89,7 @@ def chat_onecomp(
8789 temperature = temperature if temperature > 0 else None ,
8890 )
8991 generated = tokenizer .decode (
90- output_ids [0 ][inputs ["input_ids" ].shape [1 ]:],
92+ output_ids [0 ][inputs ["input_ids" ].shape [1 ] :],
9193 skip_special_tokens = True ,
9294 )
9395
@@ -139,8 +141,9 @@ def _pick_gpu_memory_utilization() -> float:
139141 free , total = torch .cuda .mem_get_info ()
140142 free_gb , total_gb = free / (1 << 30 ), total / (1 << 30 )
141143 util = round (min (max ((free_gb * 0.9 ) / total_gb , 0.1 ), 0.9 ), 2 )
142- logger .info ("GPU memory: %.1f/%.1f GiB free → gpu-memory-utilization=%.2f" ,
143- free_gb , total_gb , util )
144+ logger .info (
145+ "GPU memory: %.1f/%.1f GiB free → gpu-memory-utilization=%.2f" , free_gb , total_gb , util
146+ )
144147 return util
145148
146149
@@ -170,13 +173,20 @@ def deploy_vllm(job_id: str, model_name: str, model_dir: str) -> None:
170173 env .setdefault ("NCCL_SOCKET_FAMILY" , "AF_INET" )
171174
172175 cmd = [
173- settings .vllm_python , "-m" , "vllm.entrypoints.openai.api_server" ,
174- "--model" , model_dir ,
175- "--served-model-name" , model_name ,
176- "--port" , str (port ),
177- "--host" , "0.0.0.0" ,
176+ settings .vllm_python ,
177+ "-m" ,
178+ "vllm.entrypoints.openai.api_server" ,
179+ "--model" ,
180+ model_dir ,
181+ "--served-model-name" ,
182+ model_name ,
183+ "--port" ,
184+ str (port ),
185+ "--host" ,
186+ "0.0.0.0" ,
178187 "--trust-remote-code" ,
179- "--gpu-memory-utilization" , str (gpu_util ),
188+ "--gpu-memory-utilization" ,
189+ str (gpu_util ),
180190 "--no-enable-log-requests" ,
181191 "--enforce-eager" ,
182192 ]
@@ -200,13 +210,16 @@ def deploy_vllm(job_id: str, model_name: str, model_dir: str) -> None:
200210 with open (log_path ) as f :
201211 lines = f .readlines ()
202212 error_lines = [
203- l .rstrip () for l in lines
213+ l .rstrip ()
214+ for l in lines
204215 if "ERROR" in l or "ValueError" in l or "RuntimeError" in l
205216 ]
206217 tail = "" .join (lines [- 40 :])
207218 raise RuntimeError (
208219 f"vLLM exited with code { proc .returncode } :\n "
209- + "\n " .join (error_lines [- 20 :]) + "\n ---\n " + tail
220+ + "\n " .join (error_lines [- 20 :])
221+ + "\n ---\n "
222+ + tail
210223 )
211224 try :
212225 resp = httpx .get (health_url , timeout = 5 )
@@ -217,9 +230,7 @@ def deploy_vllm(job_id: str, model_name: str, model_dir: str) -> None:
217230
218231 else :
219232 proc .terminate ()
220- raise RuntimeError (
221- f"vLLM failed to become healthy within { _VLLM_HEALTH_TIMEOUT } s"
222- )
233+ raise RuntimeError (f"vLLM failed to become healthy within { _VLLM_HEALTH_TIMEOUT } s" )
223234
224235 inference_url = f"http://{ host } :{ port } "
225236 update_job (
@@ -266,6 +277,7 @@ def chat_vllm(
266277
267278# ── Lifecycle ─────────────────────────────────────────────────
268279
280+
269281def stop_inference (job_id : str ) -> None :
270282 _loaded_models .pop (job_id , None )
271283
0 commit comments