Files
ExperionCrawler/plans/배포테스트-qwen2.5-모델전환.md
windpacer 302183c97e feat: P&ID 연결 분석, LLM 에이전트 모드, KB 확장, MCP 서버 리팩토링
- 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 업데이트
- 정리: 진단 체크리스트 문서 삭제
2026-05-21 23:36:57 +09:00

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_mtp speculative 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가 더 느림. 이유:

  1. 27B는 MTP(Multi-Token Prediction) speculative decoding으로 한 step에 2~3토큰 생성
  2. 27B는 GB10 전용 GEMM kernel mod 적용
  3. 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이상.*상황|상황.*보고|이상.*보고|비정상.*상황|abnormalsummarize_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분 안에 통과 여부 판정 가능. 시간 낭비 방지.