11 KiB
로컬 LLM 전문화 파이프라인 — OPUS-v2 실행계획
v1 후속. v1(
ReferenceSources/.../plans/online-lora-학습-파이프라인-실행계획-byOPUS.md)의 "small dense + system 충분" 가정을 production 데이터로 폐기. Verifier를 최선두로, 35B production을 기본으로, LoRA를 가속 트랙으로.
v1 → v2 핵심 변경
| 항목 | v1 | v2 |
|---|---|---|
| Production 모델 | 소형 dense (Qwen3-8B) | A: Qwen3.6-35B-A3B-FP8 (기본 체력 floor) |
| Verifier 위치 | Phase 2 (중기, 보조) | Phase B — 최선두, 며칠 내 MVP |
| LoRA 위치 | Phase 3~4 (조건부) | Phase C — 적극 가속 (2~4주, 행동 학습) |
| "small + system 충분" 가설 | 가능 | 폐기 — production messy 환경에서 8B는 L2~L4 RAG 실패 |
| Production · LoRA 베이스 동일성 | 동일 가정 | 분리 가능성 명시 |
| 역할 분리(클라우드 프런티어) | 미고려 | Phase D — 의제화 (안전 critical 옵션) |
핵심 진단 — 사용자 발견의 반영
"RAG는 사이즈 무관"이 틀렸다 (4층 분해)
| 층 | 능력 | 사이즈 의존? | 8B (production 실측) |
|---|---|---|---|
| L1 순수 lookup | "X 가져와" → DB 반환 | ❌ 무관 | ✅ (코드 레벨) |
| L2 언제 검색할지 판단 | 모호 → 먼저 find_tags 호출, 추측 금지 | ✅ 의존 | ❌ raw_material_input 합성 |
| L3 무엇을·어떤 형식으로 | area="P6-1" 형식 준수, base_tag 구조 인식 |
✅ 의존 | ❌ area="6-1" 잘못 |
| L4 결과를 충실히 사용 | 빈 결과면 자기 인자 의심, 무필터 결과 둔갑 금지 | ✅ 의존 | ❌ 전체 area를 "6-1차"로 포장 |
→ L2~L4가 무너지면 RAG 환경을 아무리 잘 깔아도 "사실 조회조차 못함" = 기본 체력 부족. 이건 통제된 Phase 0 eval에선 안 잡힘(스캐폴드 100%, abstain 100%였음). production messy 환경에서야 드러남. 작은 모델은 production operator brain으로 부적합 — 사용자 직관 데이터 확인.
"부분 진실 fabrication"이 가장 위험
A35B도 가끔 헛소리하는데, 가장 위험한 패턴은:
- 실제 태그(p-6102) + 지어낸 상태(R-FAULT)
- 실제 데이터(전체 area 결과) + 잘못된 필터 포장("6-1차 결과")
- 실제 도구(trace_connections) + 지어낸 인자(raw_material_input)
표면이 그럴듯해 운전원이 알아채기 어려움 → 결정적 코드 검증(Verifier)이 유일한 신뢰 가능 차단선.
Phase B — Verifier MVP ★ 최선두 (3~5일)
모델 사이즈와 무관하게 결정적으로 fabrication을 차단. 35B(A) production에서도 잔여 헛소리를 잡고, LoRA(C) 학습의 실패 케이스 입력까지 자동 수집하는 핵심 인프라.
B.1 위치 — MCP 서버 미들웨어
운전원 요청
↓
[opencode 채팅] → [vLLM] → 모델 응답·툴호출
↓
━━━━ Verifier 미들웨어 ━━━━
① 결정적 룰 (코드, 모델 호출 0)
② 룰 통과 → 응답 그대로
룰 실패 → reject + error+hint를 모델에 반환 → 재시도
━━━━━━━━━━━━━━━━━━━━━━━
↓
[opencode UI]
mcp-server/server.py의 도구 함수 입구에 데코레이터/래퍼로 → 잘못된 인자 호출 즉시 차단.
모델 응답 검증은 OllamaController.cs의 응답 후처리에서 (또는 opencode → MCP proxy 단)에서 수행.
B.2 MVP 룰 카탈로그 (이번 phase에서 구현)
| # | 룰 | 어디서 적용 | 실패 시 |
|---|---|---|---|
| R1 | tag-existence — 응답·툴호출 인자에 등장한 [a-z]+-\d+[a-z]? 패턴 base_tag가 tag_metadata.base_tag ∪ pid_equipment.tag_no 에 존재? |
모든 툴 인자 + 최종 응답 텍스트 | reject + {"error":"unknown tag X","suggested":[find_tags top3]} 모델에 반환 → 재시도 |
| R2 | area-format — area= 인자가 ^P\d+(-\d+)?$ 매치? |
find_tags/active_alarms/query_events/summarize_events/generate_status_report |
reject + "use P6 or P6-1 format" |
| R3 | pump-state-enum — livevalue / corroborated_status 가 화이트리스트 안? (CONFIRMED_RUNNING / SUSPICIOUS_RUNNING / STALE / INDETERMINATE_RUNNING / STOPPED / TRIPPED; pump state: L-RUN/R-RUN/L-STOP/R-STOP/L-TRIP/R-TRIP) |
최종 응답 텍스트 스캔 | reject (R-FAULT 같은 변종 차단) |
| R4 | trace-start-tag — trace_connections(start_tag=X) 의 X가 pid_equipment 에 존재? |
도구 입구 | reject + find_tags(query=user_query) 결과를 hint로 |
| R5 | filter-applied-claim — 응답이 "X차 결과" 같은 필터된 답이라 주장하면, 실제 도구 호출이 그 sub_area로 필터됐는지 검증 |
응답 후처리 (LLM-judge 가능) | reject + "필터 미적용 결과로 답하지 말 것" |
B.3 구현 우선순위 (B 단독으로 production 즉시 안전)
- R1, R2, R4 먼저 (3가지 모두 코드 정규식·DB 조회로 결정적, 즉효) — 1~2일
- R3 (enum 화이트리스트) — 0.5일
- R5 (LLM-judge 보조) — 1~2일, 강도 높음
B.4 Verifier 출력 = LoRA 입력 (피드백 루프)
실패한 (모델 호출, hint, 재시도 후 통과한 호출) 트리플을 mcp-server/verifier/logs/*.jsonl 에 자동 축적
→ Phase C1(데이터 큐레이션)의 주 데이터셋. 즉 시스템이 학습 신호를 자기 생성.
B.5 Verifier 게이트 (B 완료 기준)
- R1~R4 구현 + py_compile + 단위 테스트
- opencode 채팅에서 "원료 투입 경로" 질문 → invention 발생 시 Verifier가 차단·재시도·올바른 호출 도달
- Verifier 로그 jsonl 자동 적재 확인
- eval 하네스에 Verifier-on/off A/B 옵션 추가 (효과 측정)
Phase A — Qwen3.6-35B-A3B production 전환 (병행, 1일)
무엇
- 기존
scripts/run-qwen3.6-35b-a3b.sh그대로 활용 (instanttensor/MTP 등 3.6 전용 플래그 유효). opencode.json기본 model을 실제 서빙 중인 vllm-36b/Qwen3.6-35B-A3B-FP8 으로 정합화.plant_context.md를 opencode system prompt에 자동 주입(또는 opencode-side 설정).- 8B는 eval/실험용으로 보존 (Verifier·LoRA 베이스 후보 평가용).
게이트
- opencode에서 "6-1차 운전 상황", "6-1차 원료 투입 경로" 질문 → A35B + Verifier 조합에서 invention 0 또는 자기교정.
Phase C — LoRA 가속 (2~4주)
Verifier(B)가 잡아내는 실패 패턴을 학습 데이터로 사용해, 행동 자체를 모델 weights에 박음. 무한 prompt 강화 = 끝없음. 학습 = 행동을 한 번에 옮김. byOPUS의 원래 의도.
C1 데이터 큐레이션 (1주)
- Verifier 로그(B.4)에서 자동 추출:
- 잘못된 인자/추측 호출 → Verifier hint → 올바른 호출 행동 쌍
- "find_tags 먼저 호출, area는 P6-1 형식, 빈 결과면 자기 의심" 행동 시퀀스
- 운전원 검수 (사람 in the loop) — 50~200건 정선
C2 SFT-LoRA (1주)
- 베이스: bf16 dense (Qwen2.5-7B-Instruct or Qwen3-8B bf16 또는 27B dense — 별도 평가). ⚠️ A(production)는 35B-A3B MoE인데, LoRA 학습은 dense에서 — production과 학습 베이스 분리 인정. → 학습된 dense 어댑터를 production에 적용하려면 (a) dense 베이스를 별도 라인으로 production 추가, (b) LoRA-distill로 35B에 행동 이전 — 어느 쪽이 비용효율적인지는 C 완료 시점에 결정.
- 타겟 모듈: attention-only(q/k/v/o) 1차, MoE expert 회피.
r=32~64, rslora, grad-ckpt unsloth.
C3 DPO/GRPO (1~2주)
- 보상 = Verifier 판정 + 운전원 👍/👎 → 선호쌍 → DPO.
- 학습 목표: calibration ("내가 모를 때 답하지 않기")를 weights 자체에 박음.
- 자기학습 collapse 위험 회피 (사람·Verifier 신호 기반).
C 게이트
- Phase 0 평가셋 + 새로 추가된 "invention" 카테고리에서 회귀 0 + invention rate 0 → 배포.
Phase D — 역할 분리 의제 (병행 논의, 결정 보류)
운전 위기/안전 critical 응답에 한해 운전원이 "강화모드" 토글 → 프런티어 클라우드(Claude/GPT-4) 호출.
- 비용 < fabrication 의 잠재 사고 비용 (안전 산업)
- 일반 응답은 로컬(A+B+C), 강화모드만 클라우드 → 비용 통제 가능
- 데이터 외부 전송 정책은 별도 검토 필요
- 결정: Phase A·B 안정화 후 2시간짜리 의사결정 회의로 채택여부 확정
의사결정 게이트 (간소)
Phase -1 (seed 정리) ✅ 완료
Phase 0 (평가셋·모델사다리) ✅ 완료 → 8B 부족 결론
↓
Phase B (Verifier MVP, 3~5d) ← 최우선
↓
Phase A (35B production 전환, 1d, B와 병행 가능)
↓
Phase C (LoRA 가속, 2~4w) — Verifier 로그를 학습 입력으로
↓
Phase D (역할 분리 결정, 2h) — A·B 안정화 후
각 phase는 이전 게이트 통과 시에만 다음으로. Verifier(B)는 모든 후속 phase의 공통 인프라.
타임라인 (개정)
| Phase | 작업 | 소요 | 비고 |
|---|---|---|---|
| -1 | seed 정리 | ✅ 완료 | knowledge/ 구축됨 |
| 0 | 평가셋·러너·모델 사다리 | ✅ 완료 | 8B = production 부적합 확정 |
| B | Verifier MVP (R1~R4) | 3~5d | 미들웨어 + 룰 코드 + 로그 적재 |
| A | 35B-A3B production 전환 + opencode 정합 | 1d | B와 병행 |
| C1 | 데이터 큐레이션 (Verifier 로그 + 검수) | 1w | |
| C2 | SFT-LoRA (bf16 dense 베이스) | 1w | production·학습 베이스 분리 |
| C3 | DPO (calibration) | 1~2w | Verifier·👍/👎 보상 |
| D | 역할분리 의사결정 회의 | 2h | A·B 안정화 후 |
운영 모니터링 (B 추가 지표)
| 항목 | 의미 |
|---|---|
| Verifier reject 비율 (룰별 / 카테고리별) | invention 압력 지표. 낮아질수록 모델·시스템 건강 |
| 재시도 후 통과율 | 자기교정 효과. 100% 가까울수록 hint 품질 좋음 |
| fabrication slip-through (수동 감사) | Verifier가 못 잡은 부분 진실 fabrication. 룰 추가 신호 |
| Verifier 로그 적재 속도 | LoRA 데이터 공급 속도 |
| (D 채택 시) 강화모드 호출 비율·비용 | 클라우드 의존도 추적 |
v1 자기비판 (명시)
- "RAG는 사이즈 무관" → 틀림. L1(lookup)만 무관. L2~L4(언제·뭘·충실히 사용)는 사이즈 의존. 사용자가 production 데이터로 정정.
- "Phase 1 무학습 레버만으로 80% 해결" → 틀림. 통제 eval에선 맞았으나 production messy 환경에선 ~50%. 통제·production 갭 과소평가.
- "small dense + 좋은 시스템 = 충분" → 틀림. 8B는 L2~L4 부족. production operator brain으로 부적합.
- "Verifier는 Phase 2 (중기 보조)" → 틀림. Verifier가 즉시 최대 leverage. v2에서 최선두로 정정.
- "production·학습 베이스 동일 모델" → 재고. A=35B-MoE, LoRA 학습=dense → 분리 가능성 인정.
- "역할 분리 미고려" → 수정. Phase D 의제화.
다음 한 수
Phase B(Verifier MVP) 착수. R1~R4 구현 작업지시서를 다른 LLM에 위임 가능한 형식으로 작성 → 완성되면 즉시 opencode에서 invention 재현 시도 → Verifier 차단 확인 → A35B로 production 전환.