converge-slot-extractor

한국어 현장 집결 조율 문장에서 슬롯 정보를 추출해 JSON으로 출력하는 GGUF 모델 3종이다. 도메인은 함정 정비(ship_maintenance)와 SI 배포(si_deploy) 두 가지다. Colab T4에서 QLoRA로 학습한 뒤 llama.cpp로 Q4_K_M 양자화했다.

파일

파일 크기
qwen3_0.6b-Q4_K_M.gguf 0.37 GiB
kanana_2.1b-Q4_K_M.gguf 1.30 GiB
qwen3_1.7b-Q4_K_M.gguf 1.03 GiB

실행에는 각 GGUF와 짝인 .prompt.json(프롬프트 앞뒤 문자열)과 grammar.gbnf(출력 JSON 문법)가 함께 필요하다. 두 파일은 학습 저장소의 Drive 경로(runs/<모델>/gguf/, finetune/export/grammar.gbnf)에 있다.

하는 일

입력 문장 예: "오후 2시 마곡 고객사 미팅. 대리님이 차 있어서 부천 지하철역 앞에서 나 태우고 감. 장비 있어서 대리님 성북구, 나 부천. 각자 언제 나가?"

출력 예 (학습 데이터 실제 정답):

{"preset": "si_deploy", "datetime": "화요일 14:00", "purpose": "고객사 미팅", "destination": "마곡 고객사", "participants": [{"name": "대리님", "origin": "성북구", "transport": "car", "pickup": null, "pickup_at": null, "unfamiliar": false, "role": "colleague"}, {"name": "나", "origin": "부천", "transport": "car", "pickup": "대리님", "pickup_at": "부천 지하철역 앞", "unfamiliar": false, "role": "site"}], "rendezvous": null, "access": {"required": true, "applied": null, "lead_min": null}, "schedule_confirmed": true, "constraints": ["luggage"], "missing": [], "out_of_scope": false}

출력 스키마

최상위 키 11개: preset, datetime, purpose, destination, participants, rendezvous, access, schedule_confirmed, constraints, missing, out_of_scope.

  • preset: ship_maintenance 또는 si_deploy. 범위 밖 요청(out_of_scope true)은 null
  • participants 각 항목 키 7개: name, origin, transport, pickup, pickup_at, unfamiliar, role
    • transport: car, transit, walk 또는 null
    • pickup: 태워주는 운전자 name, 없으면 null
    • pickup_at: 태우는 지점 (예: "부천 지하철역 앞"). 전원이 모이는 집결지가 아니라 개별 픽업 장소다. 없으면 null
    • role: site, vendor, colleague, client
  • rendezvous: 전원이 모이는 집결지 {"name", "transport_after"} 또는 null
  • access: {"required", "applied", "lead_min"} 또는 null
  • constraints: 문자열 목록 (없으면 []). 장비 있는 날은 luggage가 들어간다
  • missing: 알 수 없는 값의 위치 목록 (없으면 [])

학습 데이터

합성 데이터 591건을 템플릿과 어휘 사전 조합으로 생성했다 (gen_dataset.py, LLM 생성 아님). 입력 문장 중복 없이 train 551건 / valid 40건으로 나눴다.

원본 591건 카테고리 분포:

카테고리 건수
si_deploy_night 70
ship_regular 70
ship_emergency 60
ship_reschedule 53
follow_up 50
out_of_scope 50
si_hq_gather 50
si_client_meeting 49
missing 44
pickup 40
kakao 35
unfamiliar 20

학습 설정

  • 방식: QLoRA 4bit (nf4, double quant, 계산 fp16), gradient checkpointing
  • LoRA: rank 16, alpha 32, dropout 0.05, 대상 q/k/v/o/gate/up/down_proj
  • epoch 3, lr 2.0e-4, warmup 3%, linear 스케줄러, 유효 배치 16, max_seq_length 1152, 시드 42
  • 환경: Colab T4 GPU, torch 2.11.0+cu128, transformers 5.16.1
  • 베이스 revision 고정: Qwen3-0.6B c1899de2, kanana-1.5-2.1b-instruct-2505 7df4bc35, Qwen3-1.7B 70d244cc

결과 (valid 40건, 2026-09-18 측정)

latency는 T4 GPU fp16 generate 기준 건당 생성 시간이다. GGUF CPU 속도가 아니다.

모델 단계 exact_match slot_f1 field_acc 평균 latency_p50 (s) latency_p95 (s)
Qwen3-0.6B base (학습 전) 0.0% 32.5% 31.2% 10.18 13.83
Qwen3-0.6B lora (학습 후) 47.5% 95.3% 94.8% 9.31 11.85
Kanana-1.5-2.1B-Instruct base (학습 전) 7.5% 47.8% 53.8% 8.96 12.52
Kanana-1.5-2.1B-Instruct lora (학습 후) 85.0% 99.8% 98.8% 8.65 11.95
Qwen3-1.7B base (학습 전) 7.5% 38.1% 49.7% 7.93 14.94
Qwen3-1.7B lora (학습 후) 45.0% 96.4% 92.0% 8.80 11.98

슬롯별 lora F1 (pickup_at 포함):

모델 pickup pickup_at
Qwen3-0.6B 100.0% 100.0%
Kanana-1.5-2.1B-Instruct 100.0% 85.7%
Qwen3-1.7B 100.0% 100.0%

GGUF CPU 스모크 테스트 (스레드 2)

모델 파일 스키마 검사 CPU 생성 시간 (s)
Qwen3-0.6B qwen3_0.6b-Q4_K_M.gguf 통과 43.45
Kanana-1.5-2.1B-Instruct kanana_2.1b-Q4_K_M.gguf 통과 109.62
Qwen3-1.7B qwen3_1.7b-Q4_K_M.gguf 통과 82.18

위 시간은 Colab CPU 1건 측정값이다. 실제 서빙 환경에서는 반드시 재측정해야 한다.

베이스 모델 라이선스

  • Qwen3-0.6B, Qwen3-1.7B: Apache 2.0 (Qwen/Qwen3-0.6B, Qwen/Qwen3-1.7B)
  • Kanana-1.5-2.1B-Instruct: Apache 2.0 (kakaocorp/kanana-1.5-2.1b-instruct-2505)

사용 예시

import json
from llama_cpp import Llama, LlamaGrammar

llm = Llama(model_path="kanana_2.1b-Q4_K_M.gguf", n_ctx=2048)
pf = json.load(open("kanana_2.1b-Q4_K_M.prompt.json", encoding="utf-8"))
prompt = pf["prefix"] + "오후 2시 마곡 고객사 미팅. 대리님이 차 있어서 부천 지하철역 앞에서 나 태우고 감. 장비 있어서 대리님 성북구, 나 부천. 각자 언제 나가?" + pf["suffix"]
tokens = llm.tokenize(prompt.encode("utf-8"), add_bos=pf["add_bos"], special=True)
grammar = LlamaGrammar.from_file("grammar.gbnf", verbose=False)
out = llm.create_completion(
    prompt=tokens,
    max_tokens=pf["max_new_tokens"],
    temperature=pf["temperature"],
    grammar=grammar,
    stop=pf["stop"],
)
print(out["choices"][0]["text"])
Downloads last month
132
GGUF
Model size
2B params
Architecture
llama
Hardware compatibility
Log In to add your hardware

4-bit

Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support