17장. Project 02. LLM 추론 API 서빙
빠른 모델과 큰 모델 나눠 쓰기
병원 접수 창구는 서류 한 장으로 끝나는 일은 바로 처리하고, 판단이 필요한 일만 의사에게 보냅니다. 모두를 의사에게 보내면 줄이 길어지고, 모두 창구에서 끝내면 틀리는 일이 생깁니다. 분류 API 도 빠른 분류기가 먼저 나누고, 자신 없는 것만 LLM 에 넘깁니다.
1번에서 임베딩과 로지스틱 회귀로 만든 빠른 분류기가 모든 문의를 나눕니다. 2번에서 분류기의 확신도가 기준값보다 낮은 문의만 골라, 3번에서 LLM 에 다시 나누게 합니다. 기준값을 올리면 LLM 에 넘기는 문의가 늘어 정확해지지만 느려집니다. 여기서 접수 창구가 빠른 분류기이고, 의사가 LLM 입니다.
두 모델 견주기
| 견줄 것 | 빠른 분류기(임베딩 + 로지스틱 회귀) | LLM(Ollama qwen2.5:3b) |
|---|---|---|
| 문의 하나에 걸리는 시간 | 수 밀리초 | 수백 밀리초 |
| 필요한 것 | 분류마다 예시 문의(학습 데이터) | 분류 이름과 설명(프롬프트) |
| 잘하는 것 | 학습 데이터와 말투가 비슷한 문의 | 처음 보는 말투, 애매한 문의 |
| 확신도 | predict_proba 로 바로 나온다 | 따로 없다 |
기준값에 따라 넘기는 수
import numpy as np
labels = np.array(["배송", "교환반품", "결제", "회원", "기타"])
proba = np.array([[0.91, 0.03, 0.02, 0.02, 0.02], # 문의 셋에 분류기가 매긴 확률(설명용 숫자)
[0.35, 0.33, 0.12, 0.10, 0.10],
[0.05, 0.08, 0.62, 0.20, 0.05]])
conf = proba.max(axis=1) # 확신도: 가장 큰 확률
for th in (0.5, 0.7):
to_llm = conf < th # 기준값보다 낮으면 LLM 으로 넘긴다
print(f"기준값 {th}: LLM 으로 {to_llm.sum()}개, 분류기가 끝낸 것 {labels[proba.argmax(axis=1)][~to_llm].tolist()}")기준값 0.5 에서는 둘째 문의만 LLM 에 넘기고, 0.7 에서는 셋째 문의(확신도 0.62)도 넘깁니다. 둘째 문의는 배송(0.35)과 교환반품(0.33)이 비슷해 분류기가 자신 없는 경우입니다.
코드에 나오는 함수
| 코드 | 쉬운 뜻 |
|---|---|
proba | probability(확률)의 줄임말이다. 줄마다 문의 하나, 칸마다 분류 하나의 확률이다(설명용 숫자) |
proba.max(axis=1) | axis(축) 1 은 가로 방향이다. 줄마다 가장 큰 확률을 고른다. 이것이 확신도다 |
conf < th | th 는 threshold(문턱, 기준값)의 줄임말이다. 확신도가 기준값보다 낮은 문의는 True 다 |
to_llm.sum() | True 를 1로 세어 더한다. LLM 으로 넘길 문의 수다 |
proba.argmax(axis=1) | arg 는 argument(인자, 여기서는 자리)다. 줄마다 가장 큰 확률이 있는 자리 번호를 돌려준다 |
[~to_llm] | ~ 는 참과 거짓을 뒤집는다. LLM 으로 넘기지 않은 문의만 고른다 |
이 코드가 뜻하는 것
병원 접수 창구 직원이 서류마다 "이건 확실히 내가 처리할 수 있다"는 자신감을 매기고, 자신감이 기준보다 낮은 서류만 의사에게 넘기는 모습입니다. 여기서 직원의 자신감이 확신도, 넘기는 기준이 th 입니다.
| 줄 | 하는 일 | 쉽게 말하면 |
|---|---|---|
conf = proba.max(axis=1) | 문의 셋의 확신도 0.91, 0.35, 0.62 를 뽑는다 | 서류마다 자신감 |
for th in (0.5, 0.7): | 기준값 둘로 견준다 | 넘기는 기준을 바꿔 본다 |
기준값 0.5 줄 | LLM 으로 1개, 분류기가 ['배송', '결제'] 를 끝냈다 | 자신 없는 서류 하나만 의사에게 |
기준값 0.7 줄 | LLM 으로 2개, 분류기가 ['배송'] 만 끝냈다 | 기준을 높이니 의사에게 가는 서류가 늘었다 |
기준값을 올리면 LLM 이 맡는 몫이 커져 느려지는 대신, 애매한 문의를 더 꼼꼼히 봅니다. 비유와 다른 점은, 확신도는 분류기가 스스로 매긴 점수라 틀린 답에도 높을 수 있다는 것입니다.
주의할 점
- 확신도는 분류기가 스스로 매긴 점수라, 틀린 답에도 높게 나올 수 있습니다. 기준값은 시험 묶음으로 "넘긴 수와 정확도"의 표를 만들어 고릅니다.
- LLM 이 오류를 내면 분류기의 답으로 돌아갑니다. 느린 쪽이 고장 나도 서비스가 멈추지 않게 합니다.
- LLM 의 답은 JSON 스키마의
enum으로 다섯 분류 가운데 하나만 나오게 묶습니다. 묶지 않으면 "교환·반품" 같은 새 이름을 지어내기도 합니다.