You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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)

运行时出现两个问题:

  1. 警告:

The following model_kwargs are 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.

  1. 报错:

raise ValueError(
ValueError: Greedy methods without beam search do not support num_return_sequences different than 1 (got 4).


错误原因分析
  1. max_len警告的原因:
    Pipeline内部会自动把传入的max_length转换为max_len传递给模型,但GPT-2的generate方法只识别max_length参数,因此会抛出未使用参数的警告。这是Pipeline封装层的小问题,不影响核心功能,但可以通过特定参数或直接调用模型generate方法规避。

  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 06:47:03