
Jeeves란 무엇인가요?
Jeeves는 구조화된 결정을 내리기 전에 추론 체인을 생성하는 Jev 스타일 분류기입니다. LoRA 어댑터, 포인터 헤드, 보정된 확률, block-4 확산 드래프터가 적용된 Qwen3.5-9B를 기반으로 구축되었습니다. 저장소에는 모델 및 드래프터 코드, 학습 파이프라인, 평가 도구, 학습·개발·테스트 데이터가 포함되어 있습니다.
이 프로젝트는 자유 형식 텍스트 생성 이상의 기능이 필요한 애플리케이션을 위해 설계되었습니다. 공유 상태와 하나 이상의 질문이 주어지면 Jeeves는 Jev 호환 API를 통해 구조화된 답변과 확률을 반환합니다. 한 번의 요청에서 여러 질문을 처리할 수 있습니다.
주요 기능
- 세 가지 결정 유형: 이진
noul, 범주형choice, 순서형score질문을 지원합니다. - 결정 전 추론: 모델이 추론 체인을 생성한 다음 포인터 헤드를 사용해 사용 가능한 옵션을 평가할 수 있습니다.
- 보정된 출력: 최종 옵션 확률에는 개발 세트에 맞춰 조정된 temperature가 사용됩니다.
- Jev 호환 API: 기존 Jev 클라이언트는 핵심 요청 형식을 제출할 수 있으며, Jeeves 전용 옵션으로 추론을 제어할 수 있습니다.
- Python SDK: 포함된
sdk/패키지는 Jev의typesafe-sdk를 그대로 대체해 사용할 수 있습니다. - 확산 드래프팅: block-4 드래프터가 추론 체인 생성을 가속하고 Qwen3.5의 Gated DeltaNet 레이어를 지원합니다.
- 학습 코드: 저장소에는 SFT, CISPO, 보정, 평가, 내보내기, 드래프터 학습 구성 요소가 포함되어 있습니다.
탐욕적 추론을 2,560토큰으로 제한했을 때 README에 따르면 보류 및 도메인 외 테스트 세트에서 0.889의 정확도를 기록했으며, 공개 JevBench 231개 항목 전체에서는 0.935를 기록했습니다. 하지만 MMLU와 MMLU-Pro에서는 지식 관련 성능이 Jev에 미치지 못하므로, 벤치마크 적합성은 작업에 따라 달라집니다.
사전 요구 사항
Python 3.12와 CUDA GPU가 필요합니다. 추론 구현의 FP8 커널에는 Hopper GPU가 필요합니다. 다음 명령은 저장소 루트에서 실행하세요.
종속 항목 설치
pip install -r requirements.txt
릴리스된 가중치 다운로드
Hugging Face CLI를 사용해 공개된 9B 체크포인트와 block-4 드래프터를 다운로드하세요.
hf download PostHog/jeeves --local-dir jeeves-weights
릴리스된 모델은 Hugging Face에서 사용할 수 있습니다.
API 서버 시작
python -m inference.serve --model jeeves-weights --drafter jeeves-weights/drafter_k4.safetensors --port 8009
이 명령은 포트 8009에서 Jev 호환 서비스를 시작합니다. 포함된 Python 클라이언트는 기본적으로 http://127.0.0.1:8009을 사용하고 API 키가 필요하지 않으며, 응답을 최대 120초 동안 기다립니다.
첫 번째 결정 요청 보내기
/v1/systemone 엔드포인트는 state, questions 맵, 선택적 추론 제어 옵션을 받습니다. 다음 요청은 고객 문제를 담당 부서로 라우팅하고, 에스컬레이션이 필요한지 결정하며, 고객의 불만 정도를 평가하도록 Jeeves에 요청합니다.
curl -s localhost:8009/v1/systemone \
-H 'content-type: application/json' \
-d '{
"state": "Shoes arrived two weeks late and in the wrong size. Also I see two charges on my card.",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"returns": "Exchanges, refunds, wrong or damaged items",
"shipping": "Delivery status, delays, lost packages",
"billing": "Charges, invoices, payment problems"
}
},
"escalate": {
"type": "noul",
"instructions": "Does this need urgent human attention?"
},
"frustration": {
"type": "score",
"instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]
}
},
"options": {"max_think": 512}
}'
질문 유형 이해하기
choice: 이름이 지정된 대안 중 하나를 선택하고 선택된 키, 확률, 신뢰도를 반환합니다.noul: 예/아니요 형식의 결정을 나타내며 숫자형noul값을 반환합니다.score: 순서가 있는 레이블 목록을 평가하고 숫자형 점수, 범례, 확률, 신뢰도를 반환합니다.
응답에는 입력, 출력, 추론 토큰 수와 총 지연 시간을 포함한 사용량 정보도 들어 있습니다. 동일한 요청의 질문들은 병렬로 추론할 수 있습니다.
Python에서 Jeeves 사용하기
포함된 SDK 설치
pip install ./sdk
타입이 지정된 질문 만들기
from jeeves_sdk import Choice, Noul, Score, TypeSafeClient
with TypeSafeClient() as client:
result = client.system_one(
state="두 번 결제되었습니다. 도와주세요.",
questions={
"billing": Noul(
instructions="청구와 관련된 문제인가요?"
),
"tone": Choice(
instructions="어조는 어떤가요?",
criteria={"calm": None, "angry": None},
),
"urgency": Score(
instructions="얼마나 긴급한가요?",
criteria=["기다려도 됨", "이번 주", "오늘"],
),
},
max_think=768,
return_reasoning=True,
)
print(result.nouls["billing"].noul)
print(result.choices["tone"].choice)
print(result.scores["urgency"].score)
print(result.reasoning["tone"].text)
TypeSafeClient는 반환된 값을 질문 유형별로 그룹화합니다. return_reasoning=True로 설정하면 각 질문의 추론 텍스트도 사용할 수 있습니다. README에서는 학습 중 언어 일관성 보상이 사용되지 않았으므로 추론 과정이 반드시 해석하기 쉬운 것은 아니라고 주의를 줍니다.
다른 서버에 연결
클라이언트는 기본적으로 http://127.0.0.1:8009를 대상으로 합니다. 서버가 다른 주소에서 실행될 때는 JEEVES_BASE_URL 환경 변수를 설정하세요.
export JEEVES_BASE_URL=http://your-server:8009
추론 및 지연 시간 제어
선택 사항인 options 객체는 네 가지 추론 제어 기능을 제공합니다. 이에 대응하는 서버 플래그를 사용해 서버 전체의 기본값을 설정할 수 있습니다.
think: 기본값은true입니다. 추론 과정을 생성하지 않고 프롬프트에 바로 답하도록 하려면false로 설정하세요.max_think: 기본값은2560입니다. 모델이 답하기 전에 각 추론 과정을 지정된 토큰 수에서 잘라냅니다.nothink_threshold: 기본값은null입니다. 설정하면 추론을 생략할 확률이 임계값 이상일 때 Jeeves가 추론을 건너뜁니다.return_reasoning: 기본값은false입니다. 응답에 추론 텍스트를 포함하려면 활성화하세요.
지연 시간 프로필 선택
README의 325개 질문 개발 평가에서 전체 추론은 0.825의 정확도, 평균 1,138개의 추론 토큰, 3.3초의 중앙값 지연 시간을 기록했습니다. max_think를 768로, nothink_threshold를 0.9로 설정하면 정확도 0.806, 평균 추론 토큰 344개, 중앙값 지연 시간 2.0초를 기록했습니다. 추론을 비활성화하면 약 0.3초에 0.775의 정확도를 얻었습니다.
실용적인 균형 설정은 다음과 같습니다.
{
"options": {
"max_think": 768,
"nothink_threshold": 0.9,
"return_reasoning": false
}
}
전체 추론은 지연 시간이 길게 늘어지는 구간이 있습니다. 보고된 p90은 17.1초입니다. 응답 시간이 중요하다면 더 짧은 추론 과정이나 신뢰도 기반 추론을 사용하세요.
Jeeves의 의사 결정 방식
Jeeves는 Qwen 토크나이저의 사용 빈도가 낮은 토큰을 사용해 상태, 질문 지침, 답변 선택지를 형식화합니다. 그런 다음 think 마커로 시작하는 추론 과정을 생성합니다. 추론 후에는 결정 마커 앞에 질문과 선택지를 다시 배치합니다.
포인터 헤드는 결정 마커의 쿼리 프로젝션과 각 선택지 경계의 키 프로젝션 사이에서 스케일 조정된 내적을 계산합니다. 소프트맥스는 이 점수를 확률로 변환하고, 개발 세트에 맞춰 학습한 온도가 이를 보정합니다. README의 절제 실험에 따르면 특수 프롬프트 토큰을 일반 레이블로 바꾸거나 추론 후 질문을 반복하지 않으면 성능이 저하되었습니다.
확산 드래프터
선택 사항인 드래프터는 추측 디코딩을 통해 추론 생성을 가속합니다. Orthrus 확산 방식을 Qwen3.5의 Gated DeltaNet 레이어에 맞게 조정하여 마스크 토큰이 컨볼루션 후 키와 값에 교차 어텐션할 수 있도록 합니다.
보고된 단일 질문 처리량은 일반 그래프 탐욕 디코딩의 초당 109개 체인 토큰에서 블록 4 사용 시 초당 176개 토큰으로 증가합니다. 블록 8은 초당 193개 토큰에 도달하지만, 여러 질문을 배치할 때도 비용이 낮기 때문에 블록 4가 기본값으로 유지됩니다. 블록 4로 8개 질문을 배치하면 전체적으로 초당 약 960개의 체인 토큰을 처리할 수 있습니다.
학습한 체크포인트 제공
Jeeves는 학습 중 LoRA를 사용합니다. 학습한 체크포인트를 제공하기 전에 독립 실행형 모델로 병합하고 이에 맞는 드래프터 파일을 지정하세요.
python export.py runs/cispo/final --out runs/fused
python -m inference.serve \
--model runs/fused \
--drafter runs/drafter_k4/drafter.safetensors \
--port 8009
학습 파이프라인 재현
데이터셋 준비
준비 스크립트는 prep/public.py에 고정된 리비전으로 Hugging Face의 공개 데이터셋을 다운로드합니다. 각 원본 데이터셋에는 고유한 라이선스가 적용됩니다.
python -m prep.prep
학습 및 평가 실행
문서화된 재현 파이프라인은 GPU 8개를 사용합니다. 지도 미세 조정, CISPO 학습, 테스트 및 JevBench 평가, 모델 내보내기, 체인 생성, 블록 4 드래프터 학습을 수행합니다.
torchrun --nproc_per_node 8 train.py sft --run-dir runs/sft
torchrun --nproc_per_node 8 train.py cispo \
--run-dir runs/cispo \
--init runs/sft/final
torchrun --nproc_per_node 8 test.py runs/cispo/final
torchrun --nproc_per_node 8 jevbench.py runs/cispo/final
python export.py runs/cispo/final --out runs/fused
torchrun --nproc_per_node 8 -m drafter.gen --model runs/fused
torchrun --nproc_per_node 8 train.py drafter \
--model runs/fused \
--block 4 \
--run-dir runs/drafter_k4
공개된 레시피는 먼저 12개의 공개 데이터셋과 합성 정책 데이터에서 수집한 19,126개의 질문을 대상으로 SFT를 2 에포크 수행합니다. 그런 다음 질문당 8회의 롤아웃, temperature 1, 2,560토큰의 추론 한도를 적용한 CISPO를 사용합니다. 이후 단계에서 포화된 강화학습 풀의 포인터 헤드가 지나치게 날카로워졌기 때문에, 계획된 624단계 일정 중 402단계에서 학습을 중단했습니다. 마지막으로 개발 세트에서 보정용 temperature 하나를 피팅했습니다.
고급 사용 팁
- 관련된 결정을 일괄 처리하세요. 여러 질문을 하나의 공유 상태에 넣으면 서버가 해당 질문들의 추론 체인을 병렬로 처리할 수 있습니다.
- 쉬운 경우에는 직접 답변을 사용하세요.
nothink_threshold를 설정하여, 생각하지 않을 때의 신뢰도가 선택한 임계값보다 낮은 결정에만 추론을 사용하도록 하세요. - 지연 시간에 민감한 서비스에서는 추론을 제한하세요. 속도와 정확도 사이의 중간 지점을 원한다면 추론을 완전히 비활성화하는 대신
max_think를 낮추세요. - 필요한 경우에만 추론을 반환하세요. 애플리케이션에서 텍스트가 필요한 경우가 아니라면
return_reasoning을 비활성화 상태로 유지하세요. 특히 이러한 체인이 쉽게 해석된다고 보장할 수 없기 때문입니다. - 자체 도메인에서 평가하세요. Jeeves는 프로젝트의 테스트 분할과 공개 JevBench 티어에서 강력한 성능을 보이지만, 보고된 MMLU 및 MMLU-Pro 지식 평가에서는 Jev에 뒤처집니다.
- 비교 결과를 신중하게 해석하세요. JevBench 외부에서 공개된 Kev와 Jev의 비교는 동일한 원자료를 사용하지만 서로 다른 항목으로 수행되었습니다.
결론
Jeeves는 구조화된 Jev 스타일 출력에 테스트 시점 추론, 보정된 확률, 가속화된 체인 생성을 결합합니다. 공개된 가중치와 Jev 호환 HTTP 엔드포인트로 시작하고, 타입이 지정된 애플리케이션 코드에는 Python SDK를 사용하세요. 정확도와 지연 시간의 균형을 맞추려면 max_think와 nothink_threshold를 조정하면 됩니다. 더 깊이 사용자 지정하려는 경우 저장소에서 전체 SFT, CISPO, 보정, 내보내기 및 드래프터 파이프라인을 제공합니다.
