generate()와 stream_generate()
레슨 1의 generate()는 생성이 끝난 뒤 답 전체를 문자열 하나로 줘. 채팅 말풍선이나 터미널처럼 토큰이 생기는 즉시 보여주고 싶다면 stream_generate()를 써. 토큰마다 조각 하나를 내놓는 Python 생성기야.
둘 다 mlx-lm의 정식 API야. generate()는 stream_generate()를 얇게 감싸 조각들을 한데 잇는 방식으로 만들어졌어. 첫 글자를 빨리 보여주는 게 중요하면 스트리밍을, 끝난 답만 필요하면 버퍼링을 골라.
스트림에는 텍스트보다 많은 게 들어 있어
매번 나오는 값은 토큰 하나가 아니라 여러 정보를 담은 GenerationResponse 객체야. 실제로 자주 쓸 필드는 이래.
.text— 이번 단계에 새로 생긴 텍스트 조각이야. 보통 토큰 하나고, 가끔은 나뉘어 전송된 유니코드 글자의 일부야..finish_reason— 생성 중에는None이고, 마지막에는 멈춤 토큰을 만났다면'stop',max_tokens에 닿았다면'length'야..generation_tokens— 지금까지 생성한 토큰 수야..generation_tps— 생성 시작 뒤 측정한 초당 토큰 수라 실시간 처리량 표시에 좋아..peak_memory— 이번 생성에서 가장 많이 쓴 GPU 메모리 바이트야.
이 풍부한 정보가 mlx-lm의 숨은 장점이야. 처리량을 보려고 별도 측정기를 붙일 필요도 없고, 왜 멈췄는지 추측할 필요도 없어.
생성이 멈추는 세 가지 경우
- 모델이 토크나이저의 EOS 토큰을 냈어. Llama 3의
<|eot_id|>, Qwen의<|im_end|>같은 값이야. 토크나이저가 자기 EOS를 알고 mlx-lm이 그 값을 써.finish_reason='stop'이 돼. max_tokens에 닿았어. 이때는finish_reason='length'야. 제한이 없었다면 모델이 더 이어갔다는 뜻이지.- 직접 멈췄어. 생성기 반복문에서
break하면 문장 중간이라도 끝나. 특별한 종료 이유 없이 값이 더 나오지 않아.
빠른 시작 글이 자주 빼먹는 함정이 있어. 채팅 학습 모델은 매 턴 EOS 토큰을 보고 멈춰. 레슨 5의 채팅 템플릿을 빼먹으면 자연스러운 끝에서 EOS를 내지 못하고 max_tokens를 채울 때까지 달리는 일이 흔해.