vllm을 이용해서 openai api로 서빙한 후 응답이 무한 루프되는 문제
안녕하세요.
모델을 다운로드 받고 vllm을 이용해 openai api 형태로 서빙하여 테스트 중 다음과 같은 문제가 확인되었습니다.
아래 처럼 요청하면 응답이 max_tokens 만큼 생성된 후 종료됩니다. (응답 무한루프)
curl http://localhost:9090/v1/chat/completions \-H "Content-Type: application/json"
-d '{
"model": "naver-hyperclovax/HyperCLOVAX-SEED-Think-14B",
"messages": [
{"role": "system", "content": "- The AI language model is named "CLOVA X" and was developed by NAVER.\n- Today is Friday, July 18, 2025."},
{"role": "user", "content": "Explain in as much detail as possible the relationship between the Schrödinger equation and quantum mechanics."}
],
"top_k": -1,
"temperature": 0.5,
"top_p": 0.6,
"repetition_penalty": 1.05,
"stop": [
"<|im_end|><|endofturn|>",
"<|im_end|><|stop|>",
"<|endofturn|>",
"<|stop|>",
"<|im_end|>"
],
"max_tokens": 8192
}'아래 처럼 요청하면 응답이 정상적으로 오고 있습니다.
curl http://localhost:9090/v1/completions \-H "Content-Type: application/json"
-d '{
"prompt": "<|im_start|>tool_list\n<|im_end|>\n<|im_start|>system\n- The AI language model is named "CLOVA X" and was developed by NAVER.\n- Today is Friday, July 18, 2025.<|im_end|>\n<|im_start|>user\nExplain in as much detail as possible the relationship between the Schrödinger equation and quantum mechanics.<|im_end|>\n<|im_start|>assistant/think\n",
"top_k":-1,
"temperature":0.5,
"top_p":0.6,
"repetition_penalty":1.05,
"stop":["<|im_end|><|endofturn|>", "<|im_end|><|stop|>"],
"max_tokens":8192,
skip_sp> "skip_special_tokens":false
}'
vllm 실행시 chat-template 옵션은 사용하지 않았습니다.
직접 프롬프트를 지정해서 보내면 응답이 오고 있는 것으로 보아 message 배열 형태로 보낸 후
vllm 내부적으로 chat template 형태로 변환할때 호환성 문제가 있는 것으로 보입니다.
open-webui와 같은 오픈소스 채팅 플랫폼은 openai api 형태의 request 요청을 'v1/chat/completions' 주소를 기본으로 하고 있어 확인이 필요해 보입니다.
감사합니다.
안녕하세요, @lovedownload 님
즉 동일한 출력이 기대되는 Chat Completion API와 Completion API의 응답이 다른 것에 대한 제보로 이해하였습니다.
vLLM chat completion에서 문제가 있는지 확인해보겠습니다.
제보주신 내용에서 두 요청의 "stop"이나 "skip_special_tokens"의 값이 다르게 주어졌는데, 이를 통일하여서도 한 번 테스트 해보실 수 있을까요?
또, Chat Completion의 응답이 계속 나오는 과정에서의 응답이 정합성의 문제가 있는 상황인지 아니면 정상적인 응답이나 Completion API와 결과만 차이가 있는 것인지도 궁금합니다.
감사합니다.
안녕하세요.
동일한 옵션으로 진행해보니 'stop' 값은 배열이라 상관이 없고 'skip_special_tokens' 값에 영향을 받은 것으로 보입니다.
이 옵션의 기본값이 'false'로 알고 있는데 별도 지정을 하지 않으면 'true'로 처리되고 있네요.
'skip_special_tokens' 을 지정하지 않아 'true'로 처리될 경우 데이터 정합성에는 문제가 없고 정상적인 답변이 max_tokens 값만큼 반복되고 있습니다. (중복 답변)
(이런 내용이 model card에 있으면 도움이 되겠습니다.)
감사합니다.
추가적으로 vllm openai api를 이용해서 function calling 하는 방법도 model card에 추가해 주시면 감사하겠습니다.
위에 제보주신 요청들(Chat Completion과 Completion)의 결과가 동일하기를 기대하나 결과가 달라진 주 이유는,
vLLM 서버 실행 시 --reasoning-parser 옵션을 주지 않았기 때문에, Chat Completion 입력 맨 뒤에 thinking 모드 시작 토큰("/think\n")이 붙지 않았기 때문입니다.
우선 원인은 위와 같이 파악된 상태이고, 팀내에서 추가 가이드 및 예제를 통해 안내 드릴 수 있도록 하겠습니다.
감사합니다.
우선 간단히 아래와 같이 테스트해보실 수 있을 것 같습니다.
서버 실행 시
--enable-reasoning(vLLM v0.9에선 deprecate되었으므로 필요 없음) --reasoning-parser hcx 옵션 추가 필요
요청 날릴 시
reasoning 모드 키고 싶을 때: "chat_template_kwargs": {"force_reasoning": true}
reasoning 모드 끄고 싶을 때: "chat_template_kwargs": {"skip_reasoning": true}
자세한 예제는 아래 @kibitzing 님이 tool calling에 대해서 작성해주신 것처럼, 모델 카드 쪽으로 안내드리겠습니다.
@lovedownload 님 안녕하세요?
function calling 가이드입니다.
vllm serving
vllm serve naver-hyperclovax/HyperCLOVAX-SEED-Think-14B --trust_remote_code --enable-auto-tool-choice --tool-call-parser hcx
- 기존 서빙 스크립트에서
--enable-auto-tool-choice --tool-call-parser hcx
를 추가합니다.
- 기존 서빙 스크립트에서
request 예시
curl -X POST http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "naver-hyperclovax/HyperCLOVAX-SEED-Think-14B",
"messages": [
{"role": "user", "content": "Could you please tell me the current weather conditions in Boston, MA in Celsius?"}
],
"stop": ["<|im_end|><|stop|>", "<|im_end|><|endofturn|>"],
"max_tokens": 8192,
"skip_special_tokens": false,
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Retrieves the current weather conditions for a specified city and state.",
"parameters": {
"type": "dict",
"required": ["location"],
"properties": {
"location": {
"type": "string",
"description": "The location for which to get the weather, in the format of \'\\'City, State\\'', such as \'\\'San Francisco, CA\\'' if State for the city exists. \'\\'City, Country\\'' if State for the city does not exist. Use short form for state."
},
"unit": {
"type": "string",
"description": "The unit of temperature for the weather report.",
"enum": ["celsius", "fahrenheit"],
"default": "fahrenheit"
}
}
}
}
}
]
}'
네. 확인 감사드립니다.