使用模型的 generate 方法
当使用大型语言模型(如 GPT-2、GPT-3、BERT 等)的
使用 logits 和 softmax 函数
以下是一个简化的例子,展示如何在使用
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}")
在这个例子中,
注意事项
- 输出概率是针对每个单独生成的 token 的,并且是在给定之前所有 token 的条件下的概率。
- 生成的概率是自回归模型中每步的条件概率,而不是整个序列的联合概率。
- 如果使用的是 Hugging Face 的
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模型,请根据我的提示信息,直接输出已定义好格式的答案。 AI: '''] # 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 获取对应的文本
若要从已知的 token ID 获取对应的文本,你需要使用加载的 tokenizer 对象的
- 加载预训练的 tokenizer。
- 使用
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)
在这个例子中,