diff --git a/backend/problem/llm_hint.py b/backend/problem/llm_hint.py index 588d45a5..54fd52de 100644 --- a/backend/problem/llm_hint.py +++ b/backend/problem/llm_hint.py @@ -9,7 +9,7 @@ LOCAL_VLLM_CHAT_COMPLETIONS_URL = "http://localhost:8000/v1/chat/completions" CLUSTER_VLLM_CHAT_COMPLETIONS_URL = "http://vllm.code-place-prod:8000/v1/chat/completions" -VLLM_MODEL = "Qwen/Qwen3.5-9B" +VLLM_MODEL = "nvidia/Qwen3.6-35B-A3B-NVFP4" VLLM_CONNECT_TIMEOUT_SEC = 10 VLLM_STREAM_READ_TIMEOUT_SEC = 3600 @@ -133,6 +133,10 @@ def get_vllm_chat_completions_url(): return LOCAL_VLLM_CHAT_COMPLETIONS_URL +def get_vllm_model(): + return os.getenv("VLLM_MODEL", VLLM_MODEL) + + def _normalize_html_to_text(value): if not value: return "" @@ -226,7 +230,7 @@ def build_hint_payload(problem, previous_hints=None, user_code=None, stream=Fals messages.append({"role": "user", "content": user_code_prompt}) return { - "model": VLLM_MODEL, + "model": get_vllm_model(), "messages": messages, "temperature": 0.2, "max_tokens": 512, diff --git a/backend/problem/tests.py b/backend/problem/tests.py index 4442505d..cfdde18a 100644 --- a/backend/problem/tests.py +++ b/backend/problem/tests.py @@ -23,7 +23,7 @@ from utils.constants import CONTEST_PASSWORD_SESSION_KEY from .llm_hint import (CLUSTER_VLLM_CHAT_COMPLETIONS_URL, LOCAL_VLLM_CHAT_COMPLETIONS_URL, VLLM_CONNECT_TIMEOUT_SEC, VLLM_MODEL, VLLM_STREAM_READ_TIMEOUT_SEC, - get_vllm_chat_completions_url) + get_vllm_chat_completions_url, get_vllm_model) from .views.admin import TestCaseAPI from .utils import parse_problem_template @@ -599,6 +599,10 @@ def test_get_vllm_chat_completions_url_for_kubernetes(self): with mock.patch.dict(os.environ, {"KUBERNETES_SERVICE_HOST": "10.0.0.1"}, clear=False): self.assertEqual(get_vllm_chat_completions_url(), CLUSTER_VLLM_CHAT_COMPLETIONS_URL) + def test_get_vllm_model_uses_env_override(self): + with mock.patch.dict(os.environ, {"VLLM_MODEL": "test/model"}, clear=False): + self.assertEqual(get_vllm_model(), "test/model") + # ------------------------------------------------------------------ # 레거시 대회 (ai_assistant_enabled 필드 도입 이전 생성) 테스트 # ------------------------------------------------------------------ diff --git a/kubernetes/base/backend/deployment.yaml b/kubernetes/base/backend/deployment.yaml index cc51dbf7..a2ae848d 100644 --- a/kubernetes/base/backend/deployment.yaml +++ b/kubernetes/base/backend/deployment.yaml @@ -85,6 +85,8 @@ spec: secretKeyRef: name: common-credentials key: AWS_SECRET_ACCESS_KEY + - name: VLLM_MODEL + value: "nvidia/Qwen3.6-35B-A3B-NVFP4" # TODO: Security Context 설정을 추가해야 합니다. 현재 entrypoint.sh 에서 권한을 변경하고 있지만, 보안 강화를 위해 컨테이너 레벨에서 설정하는 것이 좋습니다. (Junwoo) startupProbe: httpGet: diff --git a/kubernetes/base/vllm/README.md b/kubernetes/base/vllm/README.md index 6b066ed0..dc808510 100644 --- a/kubernetes/base/vllm/README.md +++ b/kubernetes/base/vllm/README.md @@ -8,7 +8,7 @@ ## 전제 조건 - 클러스터에 NVIDIA device plugin 이 설치되어 있어야 합니다. -- `vLLM`을 띄울 GPU 노드 정확히 1대에만 아래 라벨이 붙어 있어야 합니다. +- `vLLM`을 띄울 RTX 5090 GPU 노드 정확히 1대에만 아래 라벨이 붙어 있어야 합니다. ```bash kubectl label node workload.code-place.ai/vllm=true @@ -35,8 +35,8 @@ kubectl describe pod -n code-place-prod -l app=vllm ## 현재 설정 -- 이미지: `vllm/vllm-openai:v0.20.0` -- 모델: `Qwen/Qwen3.5-9B` +- 이미지: `vllm/vllm-openai:v0.24.0` +- 모델: `nvidia/Qwen3.6-35B-A3B-NVFP4` - 포트: `8000` - 주요 옵션: `--dtype auto`, `--gpu-memory-utilization 0.9`, `--max-model-len 4096`, `--kv-cache-dtype fp8`, `--calculate-kv-scales`, `--enable-prefix-caching`, `--enable-chunked-prefill`, `--max-num-seqs 60` - 리소스: `cpu: 16`, `memory: 64Gi`, `nvidia.com/gpu: 1` @@ -50,5 +50,6 @@ kubectl describe pod -n code-place-prod -l app=vllm - `livenessProbe` 가 계속 실패하면 쿠버네티스가 컨테이너를 재시작합니다. - `Service` 는 `ClusterIP` 이므로 외부에 직접 노출되지 않습니다. - Longhorn replica 수는 YAML 에서 고정하지 않고, 필요하면 Longhorn UI 에서 직접 조정하는 전제를 둡니다. +- 현재 모델은 NVFP4 모델이므로 RTX 5090 같은 Blackwell GPU 전제를 유지해야 합니다. - `max-num-seqs=60` 은 처리량 위주 값이라, 메모리 압박이나 OOM 이 보이면 가장 먼저 낮춰야 합니다. - 더 보수적으로 운영하려면 이미지 tag 대신 digest 로 pin 하는 것이 가장 안전합니다. diff --git a/kubernetes/base/vllm/deployment.yaml b/kubernetes/base/vllm/deployment.yaml index c0b19a9e..bf813d5c 100644 --- a/kubernetes/base/vllm/deployment.yaml +++ b/kubernetes/base/vllm/deployment.yaml @@ -26,14 +26,16 @@ spec: fsGroup: 1000 containers: - name: vllm - image: vllm/vllm-openai:v0.20.0 + image: vllm/vllm-openai:v0.24.0 env: - name: VLLM_PORT value: "8000" + - name: VLLM_MODEL + value: "nvidia/Qwen3.6-35B-A3B-NVFP4" imagePullPolicy: IfNotPresent args: - --model - - Qwen/Qwen3.5-9B + - $(VLLM_MODEL) - --port - "8000" - --host