Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions backend/problem/llm_hint.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 ""
Expand Down Expand Up @@ -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,
Expand Down
6 changes: 5 additions & 1 deletion backend/problem/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 필드 도입 이전 생성) 테스트
# ------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions kubernetes/base/backend/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
7 changes: 4 additions & 3 deletions kubernetes/base/vllm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
## 전제 조건

- 클러스터에 NVIDIA device plugin 이 설치되어 있어야 합니다.
- `vLLM`을 띄울 GPU 노드 정확히 1대에만 아래 라벨이 붙어 있어야 합니다.
- `vLLM`을 띄울 RTX 5090 GPU 노드 정확히 1대에만 아래 라벨이 붙어 있어야 합니다.

```bash
kubectl label node <gpu-node-name> workload.code-place.ai/vllm=true
Expand All @@ -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`
Expand All @@ -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 하는 것이 가장 안전합니다.
6 changes: 4 additions & 2 deletions kubernetes/base/vllm/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down