# 로컬 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 즉시 안전) 1. **R1, R2, R4** 먼저 (3가지 모두 코드 정규식·DB 조회로 결정적, 즉효) — 1~2일 2. **R3** (enum 화이트리스트) — 0.5일 3. **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 자기비판 (명시) 1. **"RAG는 사이즈 무관"** → **틀림.** L1(lookup)만 무관. L2~L4(언제·뭘·충실히 사용)는 사이즈 의존. 사용자가 production 데이터로 정정. 2. **"Phase 1 무학습 레버만으로 80% 해결"** → **틀림.** 통제 eval에선 맞았으나 production messy 환경에선 ~50%. 통제·production 갭 과소평가. 3. **"small dense + 좋은 시스템 = 충분"** → **틀림.** 8B는 L2~L4 부족. production operator brain으로 부적합. 4. **"Verifier는 Phase 2 (중기 보조)"** → **틀림.** Verifier가 즉시 최대 leverage. v2에서 *최선두*로 정정. 5. **"production·학습 베이스 동일 모델"** → **재고.** A=35B-MoE, LoRA 학습=dense → 분리 가능성 인정. 6. **"역할 분리 미고려"** → **수정.** Phase D 의제화. --- ## 다음 한 수 **Phase B(Verifier MVP) 착수.** R1~R4 구현 작업지시서를 다른 LLM에 위임 가능한 형식으로 작성 → 완성되면 즉시 opencode에서 invention 재현 시도 → Verifier 차단 확인 → A35B로 production 전환.