- P&ID: 연결 분석 API, Prefix 규칙 관리, 카테고리 분류, DXF 그래프 빌드 - LLM: 대화 요약, tool card 영구 보존, 시계열 차트(uPlot), 에이전트 모드 - KB: 청크 미리보기, Field Instrument Inference, 인증/Qdrant 클라이언트 - MCP: 서버 기능 확장, 파이프라인 수정, timeout 개선 - Frontend: P&ID UI, LLM UI, KB UI, OPC UA Write 탭 추가 - 설정: AGENTS.md, plant_context, README, opencode.json 업데이트 - 정리: 진단 체크리스트 문서 삭제
12 KiB
배포 테스트 — Qwen2.5-7B-Instruct-FP8 모델 전환 검토
날짜: 2026-05-15
환경: NVIDIA GB10 (DGX Spark) / 통합 메모리 121 GiB / vLLM in Docker vllm_node
결론: 7B 운영 부적합. 27B 유지 결정.
TL;DR
- 동기: 27B Qwen3.6-FP8이 48 tok/s로 느리게 느껴져, 더 가벼운 7B FP8로 교체 시 속도/메모리 이득을 볼 수 있는지 검토.
- 실측: 7B FP8(
RedHatAI/Qwen2.5-7B-Instruct-FP8-dynamic)이 29.4 tok/s로 오히려 느림 (27B는qwen3_next_mtpspeculative decoding 효과). - 결정타: 7B는 도구 호출을 회피하고 가짜 데이터를 만들어냄 — 운전원 안전 위험. 도구 토글 ON·에이전트 모드 ON에도 동작 안 함.
- 조치: 27B로 즉시 복귀. 검증 중 만든 시스템 프롬프트 강화는 그대로 유지(27B에도 도움).
1. 환경 정보
하드웨어
| 항목 | 값 |
|---|---|
| GPU/CPU | NVIDIA GB10 (Grace Blackwell, unified memory) |
| 통합 메모리 | 121 GiB (시스템·GPU 공유) |
| Swap | 15 GiB |
27B 운영 구성 (baseline)
| 항목 | 값 |
|---|---|
| 모델 | Qwen/Qwen3.6-27B-FP8 |
| 메모리 점유 | ~97 GiB |
max-model-len |
262,144 (256K) |
gpu-memory-utilization |
0.80 |
speculative-config |
qwen3_next_mtp, 2 tokens |
tool-call-parser |
qwen3_coder |
| 측정 속도 | 48 tok/s |
| GB10 튜닝 mod | mods/vllm-tune-qwen--qwen3.6-27b-fp8-tp1 적용 |
2. 7B FP8 띄우기 레시피 (재현용)
모델 선택
HF에서 neuralmagic/Qwen2.5-7B-Instruct-FP8은 존재하지 않음 (404). neuralmagic이 RedHatAI로 흡수됨.
올바른 repo:
- ✅
RedHatAI/Qwen2.5-7B-Instruct-FP8-dynamic(다운로드 2378회, 공식 후속) - 그 외:
CalamitousFelicitousness/...,llmcompressor-quants/...등 community 변형
27B 종료 + 7B 기동 절차
# 1. 현재 27B vllm 프로세스만 종료 (컨테이너는 sleep infinity로 유지)
docker exec vllm_node pkill -f "vllm serve"
sleep 5
# 2. 7B FP8 기동 (launch-cluster.sh exec 패턴)
cd /home/windpacer/ai-models/spark-vllm-docker
./launch-cluster.sh -t vllm-node-tf5 --solo -d \
exec vllm serve RedHatAI/Qwen2.5-7B-Instruct-FP8-dynamic \
--served-model-name Qwen2.5-7B-Instruct-FP8 \
--max-model-len 32768 \
--max-num-seqs 4 \
--enable-prefix-caching \
--gpu-memory-utilization 0.30 \
--port 8000 --host 0.0.0.0 \
--enable-chunked-prefill \
--enable-auto-tool-choice \
--tool-call-parser hermes \
--trust-remote-code \
-tp 1
27B 명령에서 제거한 인자 (Qwen3 전용)
| 인자 | 이유 |
|---|---|
--apply-mod mods/vllm-tune-qwen--qwen3.6-27b-fp8-tp1 |
Qwen3.6-27B 전용 GEMM kernel config |
--load-format instanttensor |
Qwen3 instant tensor 최적화 |
--reasoning-parser qwen3 |
Qwen3 reasoning trace (Qwen2.5 미지원) |
--default-chat-template-kwargs '{"preserve_thinking":true}' |
Qwen3 thinking block |
--speculative-config '{"method":"qwen3_next_mtp",...}' |
Qwen3 MTP — Qwen2.5에 적용 불가 |
--tool-call-parser qwen3_coder |
→ hermes로 교체 (Qwen2.5는 hermes 포맷) |
--max-model-len 262144 |
→ 32768로 축소 (KV 캐시 절약) |
--gpu-memory-utilization 0.80 |
→ 0.30 (7B는 메모리 적게 필요) |
--max-num-batched-tokens 32768 |
32K로 충분 |
--override-generation-config |
7B 기본값 사용 |
동기화 작업
# vllm_model 표시명을 UI에 맞게 변경
echo '{"vllm_model":"Qwen2.5-7B-Instruct-FP8"}' > mcp-server/llm-model.json
appsettings.json의 vLLM endpoint, OllamaController.cs, KbEmbeddingClient.cs 등은 변경 불필요 — 포트 8000 동일.
기동 시간
- 가중치 다운로드: 152초 (~8 GiB, 첫 회만)
- 가중치 로드: 45초
- torch.compile 캐시: ~30초
- 합계 약 4분 (캐시 후 재기동은 ~75초)
3. 검증 결과
3.1 메모리 점유
| 모델 | 점유 | 가용 |
|---|---|---|
| 27B FP8 (max-len 256K, util 0.80) | 97 GiB | 11 GiB |
| 7B FP8 (max-len 32K, util 0.30) | ~25 GiB | ~85 GiB |
3.2 순수 채팅 속도 (3회 평균)
27B FP8 + qwen3_next_mtp : 48 tok/s
7B FP8 (vanilla) : 29.4 tok/s
역설: 7B가 더 느림. 이유:
- 27B는 MTP(Multi-Token Prediction) speculative decoding으로 한 step에 2~3토큰 생성
- 27B는 GB10 전용 GEMM kernel mod 적용
- 7B는 default kernel + vanilla autoregressive
3.3 도구 호출 능력 — 결정적 검증
테스트 1: 일반 KB 질의
"5월12일 6차플랜트 이상 상황 보고해줘"
- 7B 응답:
summarize_events(since=2026-05-12T00:00:00Z, area=P6)⭕ 도구 선택·area 매핑 정확 - 단 KST→UTC 변환 일부 생략 (27B는
2026-05-11T15:00:00Z로 정확)
테스트 2: 시간 인자 정확도
"지난 30분 동안 ficq-6101.pv의 값을 표시해줘"
- 7B 응답:
time_from: 2026-05-15T14:00:00, time_to: 2026-05-15T14:30:00(현재로부터 +16시간 미래!) - 결과
count: 0→ "데이터 없습니다" 답변 (사실은 84건 존재) - 원인: 7B가 "지난 30분"의 절대 시각 계산 못 함 → 학습 데이터에서 흔한 KST 14:00 차용 후 KST→UTC 변환 생략
시스템 프롬프트 강화 후 재시도 (BuildDateContextKo에 시:분 + 상대시간 표 + 미래 금지):
- 결과: 시간은 그럴듯하게 표기되었으나 도구 호출 자체를 skip하고 가짜 값(50.2 → 51.1 단조 증가) 생성
테스트 3: 결정적 검증 프롬프트
요청:
다음 3가지를 정확히 알려줘. 도구 결과만 인용, 추측 금지.
1) ficq-6101.pv 가장 최근 1건 (값 + UTC 시각)
2) ficq-6101.sp 가장 최근 1건 (값 + UTC 시각)
3) event_history_table 전체 이벤트 수
비교:
| 항목 | 7B 답변 | 실제 DB | 판정 |
|---|---|---|---|
| 1) ficq-6101.pv | 50.2 @ 22:19:00Z |
47.4666... @ 22:23:03.055Z |
❌ |
| 2) ficq-6101.sp | 50.5 @ 22:18:00Z |
34.4000... @ 22:23:03.055Z |
❌ |
| 3) event_history_table count | 12345 |
53 |
❌ |
3가지 모두 fabrication. 특히 12345는 챗봇 demo placeholder. "도구 결과 그대로 인용"이라고 7B가 표기까지 했음에도 실제 도구 호출 없음.
UI 측 도구 호출 카드
- 도구 토글: ON ✅
- 에이전트 모드(ReAct 강제): ON ✅
- 실제 도구 카드 표시: 없음 ❌
7B가 도구 호출 자체를 회피. ReAct 프롬프트도 무시.
3.4 일반 채팅 품질
- 한국어 자연스러움: ⭕ 양호 (시스템 프롬프트 한자 금지 강화 후)
- 프로젝트 설명 등 paraphrase: ⭕ 양호
- 시스템 프롬프트 내용 활용: ⭕ 양호
4. 결론
| 사용 유형 | 7B FP8 평가 |
|---|---|
| 일반 한국어 Q&A | ⭕ 사용 가능 |
| 시스템/문서 내용 paraphrase | ⭕ 사용 가능 |
| 실시간 도구 호출 | ❌ 결정적 실패 |
| 데이터 값 정확 인용 | ❌ fabrication |
| 속도 | ❌ 27B보다 느림 |
| 메모리 절약 | ⭕ 유일한 이점 (~70 GiB 절약) |
판단 기준: 운전원이 "최근 PV값"을 물었을 때 가짜 수치(50.2 vs 실제 47.47)를 사실로 받는 것은 산업 안전 위험. 12,345 같은 명백한 placeholder를 53건으로 보고하면 운영 판단 완전 왜곡.
→ 7B 운영 부적합 확정.
5. 27B 롤백 절차
검증 종료 시 즉시 복귀.
롤백 스크립트 (/tmp/restore-27b.sh)
#!/bin/bash
# 27B vLLM 복귀
set -e
cd /home/windpacer/ai-models/spark-vllm-docker
# 현재 vllm 프로세스 종료
docker exec vllm_node pkill -f "vllm serve" 2>/dev/null || true
sleep 3
./launch-cluster.sh -t vllm-node-tf5 --solo -d \
--apply-mod mods/vllm-tune-qwen--qwen3.6-27b-fp8-tp1 \
exec vllm serve Qwen/Qwen3.6-27B-FP8 \
--served-model-name Qwen3.6-27B-FP8 \
--max-model-len 262144 \
--max-num-seqs 4 \
--enable-prefix-caching \
--gpu-memory-utilization 0.80 \
--port 8000 --host 0.0.0.0 \
--load-format instanttensor \
--enable-chunked-prefill \
--enable-auto-tool-choice \
--tool-call-parser qwen3_coder \
--reasoning-parser qwen3 \
--max-num-batched-tokens 32768 \
--trust-remote-code \
--default-chat-template-kwargs '{"preserve_thinking": true}' \
--speculative-config '{"method": "qwen3_next_mtp", "num_speculative_tokens": 2}' \
--generation-config auto \
--override-generation-config '{"temperature": 0.6, "top_p": 0.95, "top_k": 20, "min_p": 0.0, "presence_penalty": 0.0, "repetition_penalty": 1.0}' \
-tp 1
함께 복원
echo '{"vllm_model":"Qwen3.6-27B-FP8"}' > mcp-server/llm-model.json
C# 앱은 사용자 재시작 (dotnet run --project src/Web/ExperionCrawler.csproj).
로딩 시간 (캐시 hit)
- 약 75초 (가중치는 이미
~/.cache/huggingface/에 있음)
6. 향후 재시도 시 점검 항목
다른 모델/구성으로 재검토할 경우 반드시 통과해야 할 체크리스트:
필수 (이 중 하나라도 실패하면 운영 불가)
- 결정 프롬프트 (Section 3.3 테스트 3) 3개 항목 모두 도구 결과 정확 인용
- UI에서
query_pv_history/run_sql도구 카드가 시각적으로 표시됨 event_history_table전체 카운트가 실제값과 일치 (추측 불가 숫자)- 시각 인자에 미래 시각(NOW 이후) 절대 안 나옴
- 데이터 값이 단조 증가 demo 패턴(
50.2 → 51.1등)이 아님
우대 (있으면 좋음)
- 한자(중국어) 글자 응답에 섞이지 않음
- KST/UTC 라벨 정확
- 27B 대비 동등 또는 더 빠른 tok/s
plant_context.md의 area 매핑(P1~P10) 따라 인자 생성
검토 후보 (참고)
| 모델 | 비고 |
|---|---|
gemma4-quantized (사용자 우선순위) |
다음 검토 1순위. 70~80 GiB 점유 예상 (27B와 유사 위치). 배포 환경에서도 이걸 쓰기로 계획됨. 검증 시 GB10 호환 양자화 종류(AWQ/GPTQ/FP8/MXFP4 등) 확인 필요. tool-call-parser는 Gemma 전용 파서(gemma/hermes 호환 여부) 점검 |
RedHatAI/Qwen2.5-72B-Instruct-FP8 |
72B FP8 ~72 GiB. 도구 호출 신뢰성 27B에 근접 예상 |
exaone3.5:7.8b (LG) |
한국어 특화 7.8B. 함수 호출 미지원일 수 있어 사전 확인 필요 |
Qwen3-30B-A3B-Instruct-2507 |
Qwen3 차세대 MoE 30B (3B active). 출시되면 검토 가치 |
Gemma4 검토 시 사전 준비 (TODO)
- HF에서 GB10·FP8 호환 정확한 repo 식별 (예:
google/gemma-4-27b-it의 FP8/AWQ 변형, RedHatAI/neuralmagic 양자화 후속) - vLLM의 Gemma 지원 버전 확인 —
--tool-call-parser옵션 (gemma,pythonic,hermes중 어느 것) - 기존 mod 디렉토리에 Gemma 관련 자료 유무 점검 (
/home/windpacer/ai-models/spark-vllm-docker/mods/fix-gemma4-tool-parser가 이미 있음 — Gemma4 도구 파서 패치 시사) - speculative decoding 가능 여부 (Gemma3는 미지원, Gemma4는 별도 확인)
- 27B FP8 (97 GiB)을 종료한 뒤에만 충분한 여유. 동시 운영은 메모리 부족 가능성 (배포 환경 기준 80GB로 가능)
7. 부산물 — 이 검증 과정에서 추가된 코드 개선
7B 검증 실패와 무관하게 시스템 전반에 도움이 되는 변경:
| 파일 | 개선 내용 |
|---|---|
src/Web/Controllers/OllamaController.cs |
BuildDateContextKo에 KST/UTC 현재 시:분 + 상대시간 변환 표(지난 30분/1시간/24시간/오늘/어제) + 미래 시각 금지 명시 |
src/Web/Controllers/OllamaController.cs |
BaseSystemPromptKo에 한자(중국어) 금지 강화 — 자주 출현하는 9글자(请·您·是·了·我·会·什么·可以·需要) 명시 |
src/Web/Controllers/OllamaController.cs |
GetModels에 Ollama /api/show 호출 → capabilities=['embedding'] 모델(bge-m3, nomic-embed-text) 채팅 셀렉터에서 자동 제외 |
prompts/plant_context.md |
P1~P10/UTIL/PACKING area 매핑 + event_history_table vs v_tag_summary area 형식 차이 안내 + 의도별 권장 도구 표 |
mcp-server/server.py |
_CLASSIFY_RULES에 이상.*상황|상황.*보고|이상.*보고|비정상.*상황|abnormal → summarize_events 추가 |
27B에도 도움 — 그대로 유지.
8. 메모
/tmp/restore-27b.sh는 임시 파일. 재기동 후 사라짐. 영구 보관하려면scripts/restore-27b.sh로 옮기는 것 권장.- 7B 가중치는
~/.cache/huggingface/hub/models--RedHatAI--Qwen2.5-7B-Instruct-FP8-dynamic/에 캐시됨 (~8 GiB). 디스크 정리 시 삭제 가능. - 다음에 7B를 다시 시도할 경우 결정 프롬프트(Section 3.3 테스트 3)부터 30분 안에 통과 여부 판정 가능. 시간 낭비 방지.