赞
踩
generate
方法当使用大型语言模型(如 GPT-2、GPT-3、BERT 等)的 generate
方法直接产生文本时,通常返回的是文本的 token ID 序列。为了获得每个 token 的生成概率,你需要使用模型的 logits
输出。logits
是模型在softmax层之前的输出,表示模型对每个可能的下一个 token 的置信度。通过对这些 logits
应用softmax函数,可以得到概率分布。
logits
和 softmax
函数以下是一个简化的例子,展示如何在使用 generate
方法时获得生成每个 token 的概率:
- import torch
- from transformers import GPT2LMHeadModel, GPT2Tokenizer
-
- # 加载预训练模型和分词器
- tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
- model = GPT2LMHeadModel.from_pretrained('gpt2')
-
- # 编码输入文本
- input_text = "The quick brown fox"
- input_ids = tokenizer.encode(input_text, return_tensors='pt')
-
- # 生成文本,同时获取logits
- outputs = model.generate(input_ids, max_length=20, output_scores=True, return_dict_in_generate=True)
-
- # 提取logits
- logits = outputs.scores
-
- # 计算概率
- probs = [torch.softmax(log, dim=-1) for log in logits]
-
- # 获取生成文本的token ID和对应的概率
- generated_ids = outputs.sequences
- for i, token_id in enumerate(generated_ids[0][len(input_ids[0]):]):
- token_prob = probs[i][0, token_id].item()
- print(f"Token ID: {token_id}, Probability: {token_prob}")

在这个例子中,generate
方法的参数 output_scores=True
使得模型返回生成每个 token 时的 logits
。通过对 logits
应用softmax函数,我们可以得到每个 token 的生成概率。
transformers
库,确保安装了最新版本,因为不同版本的 generate
方法参数可能会有所不同。上面示例使用时可能会出现问题,下面是一个自己项目中的示例:
- #!/usr/bin/python
- # encoding: utf-8
-
- import torch
- # Load via Huggingface Style
- from transformers import AutoTokenizer
- from mplug_owl.modeling_mplug_owl import MplugOwlForConditionalGeneration
- from mplug_owl.processing_mplug_owl import MplugOwlImageProcessor, MplugOwlProcessor
- import time
- #from peft import PeftModel
- from PIL import Image
-
- # 记录开始时间
- device = torch.device('cuda:0')
- print("hahahahah1 ",device)
- start_time = time.time()
- # 效果最好
- # pretrained_ckpt = 'checkpoint-epoch5-step3600'
- src_pwd_path = "soat_nlp"
- pretrained_ckpt = src_pwd_path + '/checkpoint-epoch20-final'
-
- model = MplugOwlForConditionalGeneration.from_pretrained(
- pretrained_ckpt,
- torch_dtype=torch.bfloat16,
- ## device_map="auto"
- )
-
-
- print("hahahahah1 ",model.device)
- device = "cuda:0"
- model.to(device)
- print("hahahahah2 ",model.device)
- image_processor = MplugOwlImageProcessor.from_pretrained(pretrained_ckpt)
- tokenizer = AutoTokenizer.from_pretrained(pretrained_ckpt)
- processor = MplugOwlProcessor(image_processor, tokenizer)
- print("load model done")
-
- print(model)
- # 记录结束时间
- end_time = time.time()
-
- # 计算耗时
- elapsed_time = end_time - start_time
-
- # 打印耗时
- print("代码耗时:{:.2f}秒".format(elapsed_time))
-
- # We use a human/AI template to organize the context as a multi-turn conversation.
- # <image> denotes an image placehold.
- prompts = [
- '''
- Human: 现在你是一个AI模型,请根据我的提示信息,直接输出已定义好格式的答案。\nAI: ''']
-
- # The image paths should be placed in the image_list and kept in the same order as in the prompts.
- # We support urls, local file paths and base64 string. You can custom the pre-process of images by modifying the mplug_owl.modeling_mplug_owl.ImageProcessor
- image_list = ["26520_0.jpg", "4381_0.jpg"]
-
-
- # generate kwargs (the same in transformers) can be passed in the do_generate()
- generate_kwargs = {
- 'do_sample': True,
- 'top_k': 5,
- 'max_length': 400
- }
-
- images = [Image.open(src_pwd_path + _) for _ in image_list]
- inputs = processor(text=prompts, images=images, return_tensors='pt')
- inputs = {k: v.bfloat16() if v.dtype == torch.float else v for k, v in inputs.items()}
- inputs = {k: v.to(model.device) for k, v in inputs.items()}
- print(inputs)
- with torch.no_grad():
- outputs = model.generate(**inputs, **generate_kwargs)
-
-
- # 计算概率
- probs = torch.stack(outputs.scores, dim=1).softmax(-1)
-
- # 获取生成文本的token ID和对应的概率
- generated_ids = outputs.sequences.tolist()
- sentence = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
-
- sent_prob = probs[0][0][generated_ids[0][1]].item()
-
- print(sentence,sent_prob)
-
- # # let's stack the logits generated at each step to a tensor and transform
- # # logits to probs
- # probs = torch.stack(outputs.scores, dim=1).softmax(-1) # -> shape [3, 15, vocab_size]
- # for idx,prob in enumerate(probs[0][0]) :
- # if prob > 1e-5:
- # print(idx,prob)

其中,模型最后的输出也需要对应的修改:
outputs = self.language_model.generate(
inputs_embeds=inputs_embeds,
# 新增两行
output_scores=True,
return_dict_in_generate=True,
# input_ids=input_ids,
attention_mask=attention_mask,
**generate_kwargs,
)
就可以正常调用了。
已知token id,如何获取对应的文本:tokenizer = AutoTokenizer.from_pretrained(pretrained_ckpt)
若要从已知的 token ID 获取对应的文本,你需要使用加载的 tokenizer 对象的 decode
方法。以下是如何操作的步骤:
decode
方法将 token ID 转换为文本。- from transformers import AutoTokenizer
-
- # 加载预训练的 tokenizer
- pretrained_ckpt = 'your_pretrained_checkpoint'
- tokenizer = AutoTokenizer.from_pretrained(pretrained_ckpt)
-
- # 假设你有一个 token ID 列表
- token_ids = [101, 1037, 2143, 102] # 示例 token ID
-
- # 使用 decode 方法将 token ID 转换为文本
- text = tokenizer.decode(token_ids)
-
- print(text)
在这个例子中,token_ids
是一个包含 token ID 的列表。tokenizer.decode
方法接受这个列表,并返回对应的文本字符串。pretrained_ckpt
应该被替换为你实际使用的预训练模型的检查点名称。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。