generate() is a state machine, not a function
Under the hood, model.generate() is a token-by-token decoding loop driven by a GenerationConfig object. The config carries the strategy (do_sample, num_beams), the limits (max_new_tokens, min_new_tokens), the sampling distribution shaping (temperature, top_p, top_k, repetition_penalty), and the stopping criteria (eos_token_id, stop_strings).
Three strategies you'll actually use
- Greedy (
do_sample=False,num_beams=1): pick the argmax at every step. Deterministic. Often the right default for tool-calling, JSON, code completion. - Sampling (
do_sample=True): nucleus + top-k + temperature. The default for chat. Tunetemperature=0.7,top_p=0.9as a starting point. - Beam search (
num_beams=4): explores multiple candidate sequences. Useful for translation and summarization where there's a "single best" answer. Costly —num_beams× the work.
Stop conditions are not optional
Forgetting to set eos_token_id is the most common reason a model "loops forever." Modern instruct models often have multiple end-of-turn tokens (<|eot_id|>, <|end_of_turn|>, etc.) — pass them as a list. stop_strings matches arbitrary substrings post-decode (slower but flexible).