如何用HuggingFace Transformers Pipeline生成多文本补全(仿vLLM)且无报错
我用HuggingFace Transformers Pipeline库给提示生成多个文本补全,目标是让GPT-2这类模型生成类似vLLM默认效果的不同补全结果。但设置max_length、num_return_sequences等参数时,遇到了model_kwargs未被使用的警告,还触发了报错。
使用的代码片段:
from transformers import GPT2Tokenizer, GPT2LMHeadModel, pipeline from typing import List, Dict def process_prompts(prompts: List[str], model: GPT2LMHeadModel, tokenizer: GPT2Tokenizer, num_completions: int = 3) -> List[List[str]]: device = 0 if model.device.type == 'cuda' else -1 text_generator = pipeline("text-generation", model=model, tokenizer=tokenizer, device=device) outputs = [] for prompt in prompts: try: results = text_generator(prompt, max_length=50, num_return_sequences=num_completions, num_beams=num_completions) completions = [result['generated_text'] for result in results] outputs.append(completions) except Exception as e: print(f"Error processing prompt {prompt}: {str(e)}") return outputs if __name__ == "__main__": tokenizer = GPT2Tokenizer.from_pretrained("gpt2") model = GPT2LMHeadModel.from_pretrained("gpt2") model.to("cuda" if torch.cuda.is_available() else "cpu") example_prompts = ["Hello, how are you?"] processed_outputs = process_prompts(example_prompts, model, tokenizer, num_completions=3) for output in processed_outputs: print(output)
也曾尝试过:
results = text_generator(prompt, max_length=50, num_return_sequences=num_completions)
运行时出现两个问题:
- 警告:
The following
model_kwargsare not used by the model: ['max_len']
Note: I am aware that typos in the generate arguments can also trigger this warning, but I've checked and rechecked the arguments names.
- 报错:
raise ValueError(
ValueError: Greedy methods without beam search do not supportnum_return_sequencesdifferent than 1 (got 4).
max_len警告的原因:
Pipeline内部会自动把传入的max_length转换为max_len传递给模型,但GPT-2的generate方法只识别max_length参数,因此会抛出未使用参数的警告。这是Pipeline封装层的小问题,不影响核心功能,但可以通过特定参数或直接调用模型generate方法规避。num_return_sequences报错的原因:
Pipeline默认采用贪婪搜索策略,该策略每次选择概率最高的token,只能生成1个结果。若要生成多个不同补全,必须使用支持多序列输出的生成策略:要么用beam search(但生成结果同质化严重),要么开启随机采样(do_sample=True),这两种策略才允许num_return_sequences>1。
要实现类似vLLM的多不同补全,推荐用随机采样策略(beam search生成结果相似度高,不符合vLLM默认的多样性效果),修改后的代码如下:
from transformers import GPT2Tokenizer, GPT2LMHeadModel, pipeline from typing import List, Dict import torch def process_prompts(prompts: List[str], model: GPT2LMHeadModel, tokenizer: GPT2Tokenizer, num_completions: int = 3) -> List[List[str]]: device = 0 if model.device.type == 'cuda' else -1 # GPT2默认无pad_token,用eos_token替代,避免批量生成报错 tokenizer.pad_token = tokenizer.eos_token text_generator = pipeline( "text-generation", model=model, tokenizer=tokenizer, device=device ) outputs = [] for prompt in prompts: try: results = text_generator( prompt, max_length=50, num_return_sequences=num_completions, do_sample=True, # 开启随机采样,生成不同结果 temperature=0.7, # 控制随机性,值越高结果越多样 top_p=0.9, # nucleus采样,从概率前90%的token中选,平衡多样性与合理性 return_full_text=False, # 只返回补全部分,避免重复prompt,同时消除max_len警告 pad_token_id=tokenizer.eos_token_id # 指定pad_token_id,避免生成过程报错 ) completions = [result['generated_text'] for result in results] outputs.append(completions) except Exception as e: print(f"Error processing prompt {prompt}: {str(e)}") return outputs if __name__ == "__main__": tokenizer = GPT2Tokenizer.from_pretrained("gpt2") model = GPT2LMHeadModel.from_pretrained("gpt2") model.to("cuda" if torch.cuda.is_available() else "cpu") example_prompts = ["Hello, how are you?"] processed_outputs = process_prompts(example_prompts, model, tokenizer, num_completions=3) for idx, completions in enumerate(processed_outputs): print(f"Prompt {idx+1} completions:") for i, comp in enumerate(completions): print(f" {i+1}: {comp}")
- 添加
pad_token:GPT2原生无pad_token,用eos_token替代,解决批量生成时的填充报错问题。 - 开启
do_sample=True:启用随机采样策略,这是生成多不同补全的核心,符合vLLM默认的采样逻辑。 - 调节
temperature和top_p:控制生成的多样性与合理性,temperature越高结果越随机,top_p限制采样范围避免生成无意义内容。 - 设置
return_full_text=False:仅返回补全新内容,同时消除max_len参数不匹配的警告。 - 指定
pad_token_id:明确填充token的ID,避免生成过程中出现未知错误。
内容的提问来源于stack exchange,提问作者Charlie Parker

