当前位置:   article > 正文

大模型用model.generate 直接产生文本的id以及获得模型生成文本概率的方法

model.generate
使用模型的 generate 方法

当使用大型语言模型(如 GPT-2、GPT-3、BERT 等)的 generate 方法直接产生文本时,通常返回的是文本的 token ID 序列。为了获得每个 token 的生成概率,你需要使用模型的 logits 输出。logits 是模型在softmax层之前的输出,表示模型对每个可能的下一个 token 的置信度。通过对这些 logits 应用softmax函数,可以得到概率分布。

使用 logits 和 softmax 函数

以下是一个简化的例子,展示如何在使用 generate 方法时获得生成每个 token 的概率:

  1. import torch
  2. from transformers import GPT2LMHeadModel, GPT2Tokenizer
  3. # 加载预训练模型和分词器
  4. tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
  5. model = GPT2LMHeadModel.from_pretrained('gpt2')
  6. # 编码输入文本
  7. input_text = "The quick brown fox"
  8. input_ids = tokenizer.encode(input_text, return_tensors='pt')
  9. # 生成文本,同时获取logits
  10. outputs = model.generate(input_ids, max_length=20, output_scores=True, return_dict_in_generate=True)
  11. # 提取logits
  12. logits = outputs.scores
  13. # 计算概率
  14. probs = [torch.softmax(log, dim=-1) for log in logits]
  15. # 获取生成文本的token ID和对应的概率
  16. generated_ids = outputs.sequences
  17. for i, token_id in enumerate(generated_ids[0][len(input_ids[0]):]):
  18. token_prob = probs[i][0, token_id].item()
  19. print(f"Token ID: {token_id}, Probability: {token_prob}")

在这个例子中,generate 方法的参数 output_scores=True 使得模型返回生成每个 token 时的 logits。通过对 logits 应用softmax函数,我们可以得到每个 token 的生成概率。

注意事项
  • 输出概率是针对每个单独生成的 token 的,并且是在给定之前所有 token 的条件下的概率。
  • 生成的概率是自回归模型中每步的条件概率,而不是整个序列的联合概率。
  • 如果使用的是 Hugging Face 的 transformers 库,确保安装了最新版本,因为不同版本的 generate 方法参数可能会有所不同。

上面示例使用时可能会出现问题,下面是一个自己项目中的示例:

  1. #!/usr/bin/python
  2. # encoding: utf-8
  3. import torch
  4. # Load via Huggingface Style
  5. from transformers import AutoTokenizer
  6. from mplug_owl.modeling_mplug_owl import MplugOwlForConditionalGeneration
  7. from mplug_owl.processing_mplug_owl import MplugOwlImageProcessor, MplugOwlProcessor
  8. import time
  9. #from peft import PeftModel
  10. from PIL import Image
  11. # 记录开始时间
  12. device = torch.device('cuda:0')
  13. print("hahahahah1 ",device)
  14. start_time = time.time()
  15. # 效果最好
  16. # pretrained_ckpt = 'checkpoint-epoch5-step3600'
  17. src_pwd_path = "soat_nlp"
  18. pretrained_ckpt = src_pwd_path + '/checkpoint-epoch20-final'
  19. model = MplugOwlForConditionalGeneration.from_pretrained(
  20. pretrained_ckpt,
  21. torch_dtype=torch.bfloat16,
  22. ## device_map="auto"
  23. )
  24. print("hahahahah1 ",model.device)
  25. device = "cuda:0"
  26. model.to(device)
  27. print("hahahahah2 ",model.device)
  28. image_processor = MplugOwlImageProcessor.from_pretrained(pretrained_ckpt)
  29. tokenizer = AutoTokenizer.from_pretrained(pretrained_ckpt)
  30. processor = MplugOwlProcessor(image_processor, tokenizer)
  31. print("load model done")
  32. print(model)
  33. # 记录结束时间
  34. end_time = time.time()
  35. # 计算耗时
  36. elapsed_time = end_time - start_time
  37. # 打印耗时
  38. print("代码耗时:{:.2f}秒".format(elapsed_time))
  39. # We use a human/AI template to organize the context as a multi-turn conversation.
  40. # <image> denotes an image placehold.
  41. prompts = [
  42. '''
  43. Human: 现在你是一个AI模型,请根据我的提示信息,直接输出已定义好格式的答案。\nAI: ''']
  44. # The image paths should be placed in the image_list and kept in the same order as in the prompts.
  45. # 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
  46. image_list = ["26520_0.jpg", "4381_0.jpg"]
  47. # generate kwargs (the same in transformers) can be passed in the do_generate()
  48. generate_kwargs = {
  49. 'do_sample': True,
  50. 'top_k': 5,
  51. 'max_length': 400
  52. }
  53. images = [Image.open(src_pwd_path + _) for _ in image_list]
  54. inputs = processor(text=prompts, images=images, return_tensors='pt')
  55. inputs = {k: v.bfloat16() if v.dtype == torch.float else v for k, v in inputs.items()}
  56. inputs = {k: v.to(model.device) for k, v in inputs.items()}
  57. print(inputs)
  58. with torch.no_grad():
  59. outputs = model.generate(**inputs, **generate_kwargs)
  60. # 计算概率
  61. probs = torch.stack(outputs.scores, dim=1).softmax(-1)
  62. # 获取生成文本的token ID和对应的概率
  63. generated_ids = outputs.sequences.tolist()
  64. sentence = tokenizer.decode(generated_ids[0], skip_special_tokens=True)
  65. sent_prob = probs[0][0][generated_ids[0][1]].item()
  66. print(sentence,sent_prob)
  67. # # let's stack the logits generated at each step to a tensor and transform
  68. # # logits to probs
  69. # probs = torch.stack(outputs.scores, dim=1).softmax(-1) # -> shape [3, 15, vocab_size]
  70. # for idx,prob in enumerate(probs[0][0]) :
  71. # if prob > 1e-5:
  72. # 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 对象的 decode 方法。以下是如何操作的步骤:

  1. 加载预训练的 tokenizer。
  2. 使用 decode 方法将 token ID 转换为文本。
  1. from transformers import AutoTokenizer
  2. # 加载预训练的 tokenizer
  3. pretrained_ckpt = 'your_pretrained_checkpoint'
  4. tokenizer = AutoTokenizer.from_pretrained(pretrained_ckpt)
  5. # 假设你有一个 token ID 列表
  6. token_ids = [101, 1037, 2143, 102] # 示例 token ID
  7. # 使用 decode 方法将 token ID 转换为文本
  8. text = tokenizer.decode(token_ids)
  9. print(text)

在这个例子中,token_ids 是一个包含 token ID 的列表。tokenizer.decode 方法接受这个列表,并返回对应的文本字符串。pretrained_ckpt 应该被替换为你实际使用的预训练模型的检查点名称。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/479869
推荐阅读
相关标签
  

闽ICP备14008679号