테마 전환
Laya 실전 ①: 첫 호출과 결과 읽기
examples/ 폴더의 41개 예제는 여덟 단계의 학습 경로입니다. 이 시리즈에서는 그 예제들을 주제별로 뜯어보며, 실제 코드와 실제 출력만 바탕으로 Laya를 프로덕션처럼 쓰는 법을 정리합니다.
철학: 생성이 아니라 결정
Laya는 텍스트를 생성하지 않습니다. 상태(state)와 타입이 지정된 질문(questions)을 넘기면 확률로 된 답을 돌려줍니다. 파싱할 텍스트가 없고, 존재하지 않는 라벨을 만들어낼 수도 없습니다. usage의 output_tokens는 항상 0이며, 이것이 그 약속의 증거입니다.
가장 작은 프로그램 (예제 01)
import os
os.environ.setdefault("USE_TF", "0") # 엉뚱한 TensorFlow 설치가 로드를 막지 않도록
os.environ.setdefault("USE_TORCH", "1")
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
import laya
agent = laya.load("convaiinnovations/laya") # device=None -> CUDA, 없으면 MPS, 없으면 CPU
result = agent.predict(
{"body": "We were billed twice for March. Please refund the duplicate today."},
{"refund_requested": {
"type": "noul",
"instructions": "Does the user explicitly request a refund?",
}},
)
answer = result["answers"]["refund_requested"]
print("P(refund requested) = %.4f" % answer["noul"])
눈여겨볼 점 세 가지입니다. 첫째, 환경 변수는 laya를 import하기 전에 설정해야 합니다. 둘째, load()는 로컬 디렉터리와 허브 저장소 어디에서나 가중치를 읽습니다. 셋째, 질문은 그냥 dict입니다 — type과 instructions, 그리고 (choice/score라면) criteria.
predict()가 반환하는 것 (예제 03)
결과는 평범한 dict, 세 키입니다.
{"model": "laya-rl-agent",
"answers": {<question id>: <answer>, ...},
"usage": {"input_tokens": <배치 합계>, "output_tokens": 0,
"state_tokens": ..., "state_tokens_dropped": ...,
"truncated": ..., "truncated_questions": [...]}}
answers는 내가 지은 질문 id를 키로 쓰므로 글루 코드에서 바로 인덱싱할 수 있습니다. 질문 타입별로 답이 담고 있는 필드가 다릅니다.
choice:choice(승자 라벨),probabilities(라벨별 확률)score:score(기대 레벨, 0-기준),legend(레벨 인덱스 → 문구),probabilitiesnoul:noul(P(true))- 공통:
confidence,answer_confidence,action
confidence와 answer_confidence는 다른 숫자다
여기가 가장 흔한 오해 지점입니다. confidence는 하나의 공식으로 통일된 값이 아닙니다. choice/score에서는 정규화 엔트로피(1 − H/log k), noul에서는 max(p, 1−p)입니다. 같은 0.900이 타입에 따라 완전히 다른 의미를 갖습니다.
게이트로 써야 할 값은 answer_confidence — 보고된 답에 얹힌 확률 max(p) — 입니다. 모든 질문 타입에서 같은 정의를 쓰고, 예제 18의 신뢰도 게이트가 이 값에 임계값을 적용합니다.
단, 저장소 캘리브레이션 섹션의 경고처럼 두 체크포인트 모두 기본 상태에서는 과신하는 경향이 있습니다. 문서에 적힌 임계값은 '그 분포에 대한 정책'일 뿐이며, 실제 서비스에서는 자기 데이터로 다시 맞춰야 합니다.
usage를 읽는 법
input_tokens는 컨텍스트 길이가 아니라 배치 합계입니다. 상태는 질문마다 한 번씩 인코딩되므로, 질문이 늘면 토큰도 비례해 늘어납니다. 세 질문 호출과 한 질문 호출을 비교하면 정확히 그 관계가 확인됩니다.
그리고 잘림은 답에서 보이지 않습니다. 상태가 창(max_len에서 헤드가 쓸 여백을 뺀 크기)을 넘으면 앞부분만 남고 잘리는데, 잘린 근거로 만든 답은 근거 있는 답과 똑같이 확신에 찬 얼굴을 합니다. 잘림 여부는 usage의 truncated, state_tokens_dropped, truncated_questions만 알려줍니다 — 답을 쓰기 전에 이 보고서부터 읽는 습관을 들여야 합니다.
다음 편에서는 세 가지 질문 프리미티브 choice·score·noul을 설계 관점까지 파고듭니다.