HTTP API
laya-serve는 TypeSafe Jev /v1/systemone 와이어 프로토콜로 Laya를 노출합니다. Jev에 맞춰 작성된
클라이언트 —— hs-jev, typesafe-sdk 또는 직접 만든 것 —— 는 base URL을 이 서버로 향하게 하고 계속
동작하게 할 수 있습니다. Laya의 predict() 출력은 이미 스키마 호환되며, 서버는 HTTP 표면만
추가합니다. 하나의 의사결정 라우트, 헬스 프로브, 선택적 Bearer 검사, 요청 한도입니다.
laya-serve를 대상으로 한 클라이언트가 PHP에도 있습니다. marcreichel/laya-php는 Composer SDK(PHP 8.4+)로, enum과 속성의 클래스를 질문에 대응시키고 인스턴스를 반환하며, 배포 확인을 위해 GET /health를 읽고, 서버를 띄우지 않고도 단위 테스트할 수 있는 테스트 페이크를 함께 제공합니다.
pip install "laya[serve]"
laya-serve # http://0.0.0.0:8000
같은 진입점은 어떤 ASGI 서버에든 내장되어 실행됩니다. laya.serve.create_app()은 환경에서 만든 것
대신 주입한 Router(create_app(router))와 함께, 선택적으로 FastAPI 앱을 만듭니다.
설정
모든 것이 환경 변수이므로, 하나의 이미지가 노트북 개발 실행과 systemd 유닛을 모두 서빙합니다.
| 환경 변수 | 의미 | 기본값 |
|---|---|---|
LAYA_HOST |
바인드 주소 | 0.0.0.0 |
LAYA_PORT |
바인드 포트 | 8000 |
LAYA_ROOT_PATH |
리버스 프록시 뒤에서 서빙될 때의 공개 URL 접두사 | 비어 있음 |
LAYA_DEVICE |
모든 체크포인트에 쓸 torch 장치 | auto |
LAYA_PRELOAD |
지연이 아니라 시작 시점에 체크포인트를 빌드 | 1 |
LAYA_MODELS |
미리 로드할 쉼표 목록(english,multilingual,typed-decisions); 비어 있으면 전체 |
전체 |
LAYA_THREADS |
CPU에서 torch intra-op 스레드 상한; 물리 코어 이하로 유지 —— 논리 코어를 초과 구독하면 큰 성능 저하 | torch 기본값 |
LAYA_AUTO_TASK |
typed-decisions 체크포인트로 자동 라우팅 | 0 |
LAYA_IDLE_UNLOAD_SECONDS |
이 초만큼 유휴가 지속되면 상주 체크포인트를 언로드합니다. 다음 요청에서 그 체크포인트를 다시 로드합니다. 0은 언로드를 비활성화 | 0 |
LAYA_DEFAULT_MODEL |
언어 증거가 없는 state가 폴백할 체크포인트. ml 같은 별칭은 core가 해석하는 방식대로 해석되며, 해석할 수 없는 이름은 시작 시 서버를 중단시킵니다 |
english |
LAYA_API_KEY |
설정하면 Authorization: Bearer <key> 요구 |
없음 |
LAYA_LOG_LEVEL |
uvicorn 로그 레벨 | info |
LAYA_MAX_CONCURRENT |
인증을 통과해 동시에 허용되는 요청 수; 초과분은 503 |
16 |
LAYA_MAX_BATCH_TOKENS |
한 번의 /v1/systemone/batch 포워드 패스가 함께 담을 수 있는 토큰 수(states x 질문 수 x 행 폭). 더 큰 배치는 거부되지 않고 여러 패스로 나뉩니다 |
131072 |
LAYA_JEV_STRICT |
엄격한 Jev 와이어 계약으로 제공합니다. 루트 routing 없음, 답변별 action / answer_confidence 없음, noul 답변의 confidence 없음, usage는 input_tokens + output_tokens로 축소. 여분 필드 없이 응답을 Jev 계약으로 검증하는 클라이언트용 |
0 |
/laya 같은 접두사 아래에 게시되는 배포라면 LAYA_ROOT_PATH=/laya를 설정하십시오. FastAPI는
OpenAPI와 Swagger UI URL을 생성할 때 이것을 사용합니다. 리버스 프록시가 Laya로 요청을 전달하기 전에
/laya를 제거하도록 설정하십시오. 앱의 라우트는 내부적으로 /health와 /v1/systemone
그대로입니다.
CUDA 및 ARM64 이미지를 포함한 컨테이너는 Docker 빠른 시작을 참고하십시오.
버스트가 잦은 로컬 사용에는 LAYA_IDLE_UNLOAD_SECONDS=300을 설정하십시오. 추론과 언로드는 같은 워커에서 실행되며, 단일 또는 배치 포워드 패스가 끝나면(실패한 요청 포함) 유휴 창이 다시 시작됩니다. 다음 예측은 콜드 로드 비용을 치릅니다. 언로드는 모델 참조와 장치 캐시(Metal 포함)를 해제하지만, 프로세스 할당자가 RAM 페이지를 유지할 수 있으므로 프로세스 RSS가 체크포인트 크기만큼 줄어들지는 않습니다.
엔드포인트
GET /health
항상 열려 있고(인증 없음) 추론 중에도 응답합니다. CPU에 묶인 포워드 패스가 이벤트 루프가 아니라 자체
워커에서 실행되기 때문입니다. liveness 아래의 필드는 LAYA_API_KEY를 설정한 배포에서는 열려 있지
않습니다. bearer가 없으면 /health는 {"status": "ok"}만 답하고 그 밖에는 아무것도 답하지 않습니다.
나머지는 상주 체크포인트, 그 정확한 리비전 SHA, 장치 상태, 각 체크포인트의 마지막 폴백 이유를
지목하는데, 이는 호스트 하드웨어를 인용하기 때문입니다. 프로브에 필요한 것은 200뿐이므로
헬스체크는 영향을 받지 않고, 잘못된 bearer도 401이 아니라 여전히 200입니다. LAYA_API_KEY가
설정되지 않았다면 모든 호출자가 여기 표시된 전체 페이로드를 받습니다.
{"status": "ok", "loaded": ["english", "multilingual"], "revisions": {"english": "...", "multilingual": "..."},
"device": "cuda", "device_is_preference": false,
"checkpoint_devices": {"english": "cuda", "multilingual": "cuda"},
"cpu_fallbacks": {"english": {"count": 0, "last_reason": null}, "multilingual": {"count": 0, "last_reason": null}}}
한 서버의 답이므로 각 블록은 서로 일치합니다. revisions, checkpoint_devices, cpu_fallbacks의
모든 키는 loaded 안의 이름입니다. tests/test_serve.py가 이 샘플을 그것을 생성하는 핸들러에
대해 필드별로 고정합니다.
유휴 언로드가 활성화된 경우, 인증된 health 응답에는 idle_unload_seconds(설정된 창)와
idle_seconds(마지막 추론 요청 또는 완료 이후 시간)도 포함됩니다. 헬스 프로브는 그 시계를
리셋하지 않습니다. 유휴 언로드 후 빈 loaded 목록은 정상입니다.
status는 프로세스가 응답하는 한 항상ok입니다. 체크포인트에 대해서는 아무것도 말하지 않습니다.loaded는 메모리에 상주한 체크포인트를 나열합니다. 요청이 하나를 빌드하기 전까지는 비어 있으며,LAYA_PRELOAD=0은 프로세스를 그 상태로 둡니다.revisions는 상주 체크포인트 각각이 로드된 산출물 리비전으로,loaded와 같은 이름을 키로 합니다. 그래서 배포가 실제로 무엇을 서빙하는지 확인할 수 있습니다.device는 상주 체크포인트가 실제로 계산하는 장치이며,LAYA_DEVICE가 요청한 것과 항상 같지는 않습니다. 얻을 수 없는 GPU를 원하는 체크포인트는 조용히 CPU로 폴백하고 그래도 올바르게 답합니다. 상주하는 것이 없으면 대신 설정된 기본 설정입니다.device_is_preference는 상주하는 것이 없는 동안에만true이고, 핸들러가 측정할 수 있게 되면 곧false입니다. 그것이 설정을 보고하는 서버와 작업이 어디서 일어나는지 보고하는 서버의 차이입니다. GPU를 조용히 잃은 서버는cuda라고 계속 답하는 대신device가cpu이면서false라고 말합니다.checkpoint_devices는 체크포인트별 측정값을loaded의 이름을 키로 제공합니다.device는 그 값들 중 첫 번째입니다.cpu_fallbacks는 상주 체크포인트별로 GPU 메모리를 소진해 CPU에서 한 번 재시도된 요청을 셉니다.count는 프로세스 시작 이후,last_reason은 가장 최근 것의 오류 텍스트입니다. 강등은 실패한 요청에 국한되므로, GPU를 애초에 쓸 수 없어 CPU에서 빌드된 체크포인트는 폴백이 아니고 여기서0을 셉니다 —— 그것은device에 나타납니다.
POST /v1/systemone
하나의 요청이 state와 그에 대한 임의 개수의 질문을 담습니다:
curl -s localhost:8000/v1/systemone -H 'content-type: application/json' -d '{
"state": "I was charged twice this month, I want my money back",
"questions": {
"queue": {"type": "choice", "instructions": "Which team?",
"criteria": {"billing": "billing and refunds", "tech": "login and app issues",
"other": "everything else"}},
"urgency": {"type": "score", "instructions": "How urgent?",
"criteria": ["calm", "firm", "angry", "furious"]}
}
}'
| 필드 | 필수 | 의미 |
|---|---|---|
state |
예 | 의사결정 대상인 텍스트, 이메일, 티켓 또는 JSON 문서; 없거나 null인 state는 400 |
questions |
예 | 질문 id로 키가 잡힌 객체; 각 질문은 instructions와 criteria를 가진 choice / score / noul |
model |
아니오 | 체크포인트를 지명; 경로나 미공개 Hub id는 422, 그 밖의 값은 무시됨 (아래 참고) |
task |
아니오 | 라우팅이 결정하게 두는 대신 워크플로 이름으로 체크포인트를 강제; 알 수 없는 이름은 그 이름을 밝히며 422 |
lang |
아니오 | 언어를 지명하면 감지를 건너뛰는 언어 코드(de, en-US); 비어 있거나 인식되지 않는 코드는 감지로 넘어감 |
lang_guess |
아니오 | 클라이언트 자체 식별기에서 나온 언어 코드로, lang 다음, 감지 이전에 참조됨; 영어가 아닌 코드는 다국어 체크포인트로 라우팅 |
max_len |
아니오 | 이 요청의 전체 토큰 창, LAYA_MAX_TOKEN_BUDGET으로 상한이 걸림 |
head_max_len |
아니오 | 선택지 프롬프트가 공유하는 토큰 창, 같은 상한; 질문이 이것을 필요로 하는 때는 토큰 예산 넓히기 참고 |
min_confidence |
아니오 | [0.0, 1.0] 범위의 유보 임계값; answer_confidence가 그 아래로 떨어지는 답은 low_confidence로 표시되어 돌아오며, 답 자체는 유지됨 |
model, task, lang, lang_guess, max_len, head_max_len, min_confidence는 JSON 본문이
표현할 수 있는 Router.predict의 인수입니다. 각각은 요청이 보낼 때만 전달되므로, 없는 것은 배포
자체의 Router(...) 설정이 담당하게 둡니다. predict가 받는 다섯 개의 훅 인수 —— hooks,
on_predict_start, on_predict_end, hooks_raise, hooks_timeout —— 는 버려지지 않고 422로
거부됩니다. 훅은 서버 프로세스 안에서 실행되는 콜러블이고, 마지막 둘은 배포가 설치한 훅이 어떻게
실행되는지를 말하므로, 호출자가 보내는 어떤 값도 여기서는 의미가 없습니다. 같은 다섯은 base_url을
가진 LangChain 노드(laya.integrations.langchain)에서 클라이언트 측으로 거부되므로, 체인과 생 HTTP
클라이언트가 이제 같은 답을 받습니다.
model은 Jev 클라이언트가 계속 보낼 수 있도록 받습니다. 공개 Hugging Face id
(convaiinnovations/laya-multilingual, convaiinnovations/laya-typed-decisions), 체크포인트
이름(english, multilingual, typed-decisions)과 그 별칭이 체크포인트를 선택합니다.
convaiinnovations/laya, 그리고 경로나 Hub 저장소 id가 아닌 그 밖의 값 —— jev-1 같은 Jev id
포함 —— 은 “라우터가 고르게 하라”는 뜻이며, 응답의 routing 블록이 무엇이 왜 선택되었는지
기록합니다. 파일 시스템 경로나 미공개 Hub id처럼 보이는 값(/path/to/checkpoint, org/repo,
~/ckpt, .\ckpt)은 /v1/systemone과 /v1/systemone/batch 모두에서 422입니다. 이 서버는
그것을 로드할 수 없고, 다른 체크포인트로 답하면 그것을 숨기게 되기 때문입니다. detail은 core가
던지는 것과 같은 unknown model 텍스트에, 라우터가 고르게 하려면 model을 생략하라는
알림을 더한 것입니다.
응답
{
"model": "laya-rl-agent",
"answers": {
"queue": {"type": "choice", "choice": "billing",
"probabilities": {"billing": 0.9519, "tech": 0.0327, "other": 0.0154},
"confidence": 0.797, "answer_confidence": 0.9519,
"action": {"act_probability": 1.0}},
"urgency": {"type": "score", "score": 1.6994,
"legend": {"0": "calm", "1": "firm", "2": "angry", "3": "furious"},
"probabilities": {"0": 0.0249, "1": 0.4136, "2": 0.3985, "3": 0.1629},
"confidence": 0.1925, "answer_confidence": 0.4136,
"action": {"act_probability": 1.0}}
},
"usage": {"input_tokens": 83, "output_tokens": 0, "state_tokens": 12,
"state_tokens_dropped": 0, "truncated": false, "truncated_questions": []},
"routing": {"model": "english", "repo": "convaiinnovations/laya", "reason": "English Latin text",
"detection": {"script": "latin", "script_profile": {"latin": 1.0}, "language": "en",
"is_english": true, "language_undecided": false, "diacritic_rate": 0.0,
"non_latin_fraction": 0.0, "mixed_segment": null},
"workflow": null}
}
이 샘플은 이 서버가 실제로 준 하나의 답을 그대로 실은 것입니다. 위의 요청을 CPU의 캐시된
english 체크포인트로 처리한 것입니다. answers와 usage는 Jev 클라이언트가 디코드하는
키입니다. model은 의사결정 head의 상수 이름이고, 답한 체크포인트는 routing에 있습니다.
| 답 타입 | 키 |
|---|---|
choice |
choice(argmax 선택지), 선택지별 probabilities |
score |
score(기대 단계 인덱스, 단계 사이에 있을 수 있음), "0".. "k-1"로 키가 잡힌 probabilities, 인덱스를 단계 텍스트로 매핑하는 legend |
noul |
noul, 예 선택지의 확률 |
| 모두 | confidence, answer_confidence, action.act_probability |
| gate | abstention, abstention_threshold, low_confidence. 유보 게이트가 작성합니다 —— 아래 참고 |
gate 행은 유보 리포트(#361)이며, 호출자가 자신이 지불한 게이트가 실행되었음을 확인할 수 있는
유일한 방법입니다. min_confidence를 설정한 요청은 그것을 받고, 설정하지 않은 요청은 세 키 중
어느 것도 받지 않습니다. abstention은 세 상태 중 하나로, 게이트된 요청의 모든 답에
기록됩니다. passed(그 신뢰도가 임계값을 넘음), abstained(아래로 떨어졌고 정확히 그 답들에서
low_confidence가 true), 또는 unevaluated(답이 쓸 수 있는 신뢰도를 지니지 않아 게이트가
결정할 수 없음 —— 그것을 pass로 보고하는 것은 flag로 보고하는 것과 같은 거짓말입니다).
abstention_threshold는 그 상태들을 측정한 임계값을 그대로 되돌려주며, 그래서 클래스별
임계값을 쓰는 배치 실행이 사후에 다시 분할될 수 있습니다. min_confidence가 설정되지 않으면
세 키는 어떤 답에도 나타나지 않습니다. 부재가 리포트이고 네 번째 상태가 아니며, 호출자가
게이트 없는 실행과 통과된 게이트를 구별하는 방법입니다. 정확히 0.0인 min_confidence는
설정된 것이므로 상태가 보고되고, 아무것도 그 아래로 떨어질 수 없으므로 모든 답이 passed로
읽힙니다 —— 되돌려진 0.0이 그것을 실제 임계값에서의 pass와 구별하는 것입니다. 답 자체는
모든 상태에서 유지됩니다. 게이트는 표시만 하고 버리지 않습니다.
usage는 포워드 패스가 무엇으로부터 만들어졌는지 보고합니다. 모델이 state의 얼마를 읽는지는
문자 수가 아니라 토큰 예산이고, 예산은 max_len, head_max_len, 그리고 각 질문 자체의
선택지 프롬프트(#174)에 따라 움직이므로, 이 키들이 그 사실이 보이는 유일한 곳입니다.
usage 키 |
의미 |
|---|---|
input_tokens |
state의 행에 있는 비패드 토큰 —— 질문당 한 행이므로 컨텍스트 길이가 아니라 질문과 함께 늘어납니다 |
output_tokens |
항상 0 —— head는 한 패스로 답하며 아무것도 생성하지 않습니다 |
state_tokens |
직렬화된 state 전체가 필요로 하는 토큰 |
state_tokens_dropped |
그중 적어도 하나의 질문이 받지 못한 토큰. 질문마다 state에 남기는 여지가 달라서 질문 전체에 걸친 최악의 경우입니다 |
truncated |
그 최악의 경우가 무엇이든 떨어뜨렸을 때 true |
truncated_questions |
자신의 창이 잘린 질문의 id, 없으면 [] |
options |
어떤 질문의 선택지가 더 이상 각각 토큰 폭을 갖지 않을 때만 나타납니다. 질문 id를 키로, total(그 질문이 정의하는 선택지 수), distinct(시퀀스에 도달한 폭의 수), tokens_per_option을 가집니다 |
잘린 답도 여전히 답입니다 —— head는 주어진 증거로 결정합니다 —— 다만 문자 수로 state를 재는 호출자는 응답의 어디에서도 그 잘림을 볼 수 없습니다.
routing은 어느 체크포인트가 왜 답했는지 기록합니다:
routing 키 |
의미 |
|---|---|
model |
답한 체크포인트: english, multilingual, typed-decisions |
repo |
그 공개 Hugging Face id |
reason |
선택에 대한 문장으로, 작용한 증거를 지목합니다 |
detection |
state에 대한 laya.lang.analyse() —— script, script_profile, language, is_english, language_undecided, diacritic_rate, non_latin_fraction, mixed_segment —— 또는 라우트가 텍스트를 읽기 전에 결정했으면 null |
workflow |
질문 id가 일치하는 typed-decisions 워크플로, 또는 null |
detection은 state를 읽지 않고 결정하는 모든 경로에서 null입니다. model이나 task로
강제된 것, lang이나 lang_guess로 답한 것, 질문 id로 typed-decisions 워크플로에 일치한
것입니다. lang_guess는 자신의 키를 남기지 않습니다 —— 작용한 힌트는 reason에 지목됩니다.
model과 task 분기도 workflow를 null로 보고합니다. 질문 id가 읽히기 전에 답하기
때문입니다.
신뢰도: 서로 바꿀 수 없는 두 숫자
answer_confidence는 보고되는 답에 실린 확률 질량(max(p))입니다. 온도 스케일링이 적합하는 양이고 이 저장소의 ECE 수치가 계산되는 양이므로, 벤치마크와 알려진 한계 페이지가 기대는 게이팅 성질을 지닙니다 —— 다만 온도 적합이 당신의 트래픽에서 검증된 체크포인트에 한해서입니다.confidence는 타입마다 다른 것을 뜻합니다.choice와score에서는 정규화 엔트로피1 - H(p)/log(k)이고,noul에서는max(p_yes, p_no)입니다(여기서는answer_confidence와 같습니다).
둘을 하나의 임계값과 비교하지 마십시오. Jev에서 이식할 때의 차이도 유의하십시오. TypeSafe는
신뢰도를 (n*p_max - 1)/(n - 1)로 정의하므로, Jev 배포에서 가져온 임계값은 Laya의 엔트로피 값에
대해 다르게 게이팅합니다.
엄격한 Jev 계약: LAYA_JEV_STRICT
위의 페이로드는 전체 Laya 페이로드입니다. 클라이언트가 그것을 준수하게 하는 Jev 계약은 더 적게
정의합니다. 최상위 필드 세 개(model, answers, usage), 각 답에 계약된 키만, 그리고 두 토큰
수의 usage입니다. 여분 필드 없이 그 계약에 대해 응답을 검증하는 클라이언트 —— OpenClaw의
TypeSafe 프로바이더 플러그인이 그중 하나 —— 는 전체 페이로드를 거부하므로,
LAYA_JEV_STRICT=1은 답하기 전에 응답을 계약 위로 사영합니다. /v1/systemone과
/v1/systemone/batch 모두에서입니다.
- 루트는
model,answers,usage만 유지합니다.routing은 보내지 않습니다. choice답은choice,probabilities,confidence를 유지합니다.score답은score,probabilities,confidence,legend를 유지합니다.noul답은noul만 유지합니다.usage는input_tokens와output_tokens를 유지합니다. 잘림 사실과 축약된 선택지 상한은 보내지 않습니다.
사영은 계약된 키만 유지하고 아무것도 다시 계산하지 않습니다. 모든 값은 결과가 이미 지닌 것이므로,
엄격한 클라이언트가 읽는 확률과 점수는 전체 페이로드가 보고하는 것과 동일합니다. 기본값은
전체 페이로드로 남고, 플래그를 켠 배포는 usage가 제공하는 잘림 가시성을 잃습니다 —— 잘린
state는 그때 응답이 아니라 로그에서 보입니다. 엄격한 계약 아래에서 score criteria는 평범한
문자열로 두는 것이 좋습니다. 엄격한 클라이언트는 반환된 legend를 자신이 보낸 criteria와
비교하는데, Laya는 구조화된 criterion을 Python의 JSON으로 렌더링하므로, 자신의 criteria를
문자열화하는 JavaScript 호출자는 그것을 바이트 단위로 일치시키지 못할 수 있습니다.
성공한 응답은 Server-Timing: inference;dur=<ms>와 X-Inference-Time-Ms도 함께 지닙니다.
한도
요청 가드레일은 토큰화 이전에 검사되므로, 너무 큰 요청은 서버에 읽은 바이트 외에는 아무 비용도
치르게 하지 않습니다. 그것들은 모두 413이며, detail이 어느 한도에 걸렸는지 말합니다.
| 한도 | 값 |
|---|---|
| 요청 본문 | 2 MiB, 스트리밍 중 강제 —— 청크 분할되거나 축소 보고된 Content-Length로 우회할 수 없음 |
state |
모델에 주어지는 텍스트의 50,000자 —— 문자열 state면 문자열 자체, 객체나 배열이면 json.dumps(state, ensure_ascii=False) |
| 요청당 질문 수 | 64 |
배치 요청당 states |
64 |
choice 질문당 선택지 |
100 |
score 질문당 단계 |
32 |
| 모든 질문에 걸친 선택지 | 512 |
| 동시 허용 요청 | LAYA_MAX_CONCURRENT (16) |
/v1/systemone/batch는 다르게 경계가 정해지며, 거부에 의해서가 아닙니다. 각 state를 질문마다
한 번 토큰화하고 모든 행을 하나의 텐서로 모으므로, 필드 상한이 곱해집니다. 64 states의 64
질문은 4096행이고, 이 페이지의 다른 모든 한도가 그것을 허용합니다. 한 행의 비용은 그 폭이며,
max_len 자체가 요청 필드이므로 배치의 비용은 states x questions x width입니다.
큰 배치를 거부하는 대신, 엔드포인트는 그것을 분할합니다. 그 곱이
LAYA_MAX_BATCH_TOKENS(기본 131,072)를 넘으면 각 포워드 패스가 예산 안에 머물도록
batch_size를 고르고, Router.predict_batch가 배치를 여러 패스로 실행합니다. 모든 state는
여전히 답해지고 응답은 바뀌지 않습니다. 행이 이미 들어맞는 요청에는 batch_size가 전혀
전달되지 않으므로, 이전과 정확히 똑같이 동작합니다 —— 이는 중요합니다. 배치 모양이 부동소수점
결과를 움직일 수 있기 때문입니다. 호출자가 보낸 batch_size는 항상 우선합니다. 그것은 모양을
요청한 것입니다.
기본값에서는 256행이 한 패스로 지나갑니다 —— 64 states의 4 질문, 또는 8의 32 질문입니다. 더 큰
배치는 분할되며, max_len을 높이면 16배의 작업이 드는 대신 각 패스가 좁아집니다. 이것이
경계 짓지 않는 것은 하나의 요청이 서버를 점유하는 시간입니다. 그것은 LAYA_MAX_CONCURRENT와
단일 추론 워커이며, 50,000자 state에 걸친 하나의 /v1/systemone 요청에 대해서도 이미
참입니다.
선택지 상한은 HTTP 전용 증폭 가드입니다. 모델 자체는 선택지 토큰을 head_max_len=192 창에
맞추므로, HTTP 상한 안에 있는 질문도 선택지 텍스트를 합친 것이 그 예산을 넘으면 422로 거부될 수
있습니다. 평가 하네스는 HTTP 계층 없이 같은 요청을 프로세스 내에서 실행합니다.
오류
| 상태 | 언제 | 본문 detail |
|---|---|---|
400 |
본문이 유효한 JSON이 아니거나, 객체가 아니거나, questions가 없거나, state가 없거나 null이거나, questions가 객체가 아니거나, 본문 어딘가의 문자열이 짝이 없는 \udXXX 서로게이트 이스케이프를 담고 있음 |
무엇이 잘못되었는지 |
401 |
LAYA_API_KEY가 설정되어 있고 Bearer 토큰이 없거나 틀림 |
invalid or missing bearer token |
413 |
위의 어느 한도든 | 어느 한도이고 얼마나 초과했는지 |
422 |
질문이 잘 형성된 JSON이지만 Laya에 유효하지 않거나(알 수 없는 타입, head 예산 초과 선택지), 요청 제어(lang, min_confidence, 훅 인수)가 이 엔드포인트가 받는 형태가 아님 |
질문이나 필드의 이름과 고칠 것을 밝힘 |
500 |
다른 이유로 추론이 실패 | inference failed —— 항상 이 문자열이라 경로, 가중치, 메모리 상태가 새어 나가지 않음; 원인은 서버 로그에 있음 |
503 |
LAYA_MAX_CONCURRENT개의 요청이 이미 진행 중 |
server busy, try again later |
짝이 없는 서로게이트 400은 특이해 보이는 것입니다. 짝이 없는 \udXXX는 합법적인 JSON이지만,
그것이 지목하는 문자는 UTF-8로 인코딩될 수 없어 토크나이저가 TypeError를 일으킵니다 ——
호출자 자신의 문자열이 요청마다 트레이스백을 동반한 서버 장애로 도착하는 것입니다. 그래서 두
의사결정 라우트 모두 파싱된 본문을 훑어 홀로 있는 서로게이트를 찾아 추론에 도달하기 전에
거부합니다. 훑기는 크기 검사 뒤에 실행되므로 너무 큰 본문은 여전히 먼저 거부되고, 문자와 질문
한도가 그것이 도달할 수 있는 범위를 제한합니다. 짝을 이룬 서로게이트는 파서가 끝낼 무렵
하나의 평범한 보조 문자이므로, state 안의 이모지는 영향을 받지 않습니다.
상한 초과 부하는 대기열에 넣지 않고 거부합니다. 느린 본문을 스트리밍하면서 허용 슬롯을 쥐고 있는
클라이언트가 /health를 굶길 수 없고, 재시도는 거부된 클라이언트가 남긴 슬롯을 차지할 수 있습니다.
동시성 모델
추론은 CPU에서 수백 밀리초에서 수 초가 걸리는 동기식 torch 호출이므로 이벤트 루프에서 결코
실행되지 않습니다. 요청은 단일 워커 실행기로 넘겨지며, 이는 한 번에 하나의 포워드 패스라는 뜻입니다
—— 한 장치 위의 단일 체크포인트가 원하는 형태입니다. 허용(LAYA_MAX_CONCURRENT 세마포어)은 본문
바이트를 읽기 전에 검사되고 추론 내내 유지됩니다. 추론 게이트는 본문이 완료된 뒤에만 합류하므로,
느린 클라이언트는 허용 슬롯은 쥐지만 추론 슬롯은 결코 쥐지 않습니다.
(아직) 여기 없는 것
이 서버는 의도적으로 하나의 프로토콜만 말합니다. OpenAI 호환 엔드포인트는 없습니다. 대신 여러
질문을 한 요청에서 실행하십시오. 질문 집합마다 하나의 포워드 패스를 공유하기 때문입니다. 다른
하나의 라우트는 POST /v1/systemone/batch로, states 배열에 대해 하나의 questions 집합을
답합니다. 이 페이지에는 아직 절이 없습니다 —— 그 요청 모양은 README의 셀프 호스팅 절에
있습니다 —— 그리고 위의 모든 검사가 POST /v1/systemone에 적용되는 것과 똑같이 적용됩니다.
같은 모양의 400, 같은 unpaired-surrogate 거부, 같은 auth, admission, 크기 한도, body-control
검증, 500 매핑입니다. laya CLI와 MCP 서버는 로컬 사용을 담당합니다 ——
README를 참고하십시오.