当前位置:   article > 正文

【Pytorch神经网络实战案例】34 使用GPT-2模型实现句子补全功能(手动加载)_pytorch gpt2 新场景使用方法

pytorch gpt2 新场景使用方法

 

GPT-2 模型结构

GPT-2的整体结构如下图,GPT-2是以Transformer为基础构建的,使用字节对编码的方法进行数据预处理,通过预测下一个词任务进行预训练的语言模型。

1.1 GPT-2 功能简介

GPT-2 就是一个语言模型,能够根据上文预测下一个单词,所以它就可以利用预训练已经学到的知识来生成文本,如生成新闻。也可以使用另一些数据进行微调,生成有特定格式或者主题的文本,如诗歌、戏剧。

2 手动加载GPT-2模型并实现语句与完整句子预测

使用GPT-2模型配套的PreTrainedTokenizer类,所需要加载的词表文件比BERT模型多了一个merges文件。

2.1 代码实现:手动加载GPT-2模型并实现下一个单词预测---GPT2_make.py(第1部分)

  1. import torch
  2. from transformers import GPT2Tokenizer, GPT2LMHeadModel
  3. # 案例描述:Transformers库中的GPT-2模型,并用它实现下一词预测功能,即预测一个未完成句子的下一个可能出现的单词。
  4. # 下一词预测任务是一个常见的任务,在Transformers库中有很多模型都可以实现该任务。也可以使用BERT模型来实现。选用GPT-2模型,主要在于介绍手动加载多词表文件的特殊方式。
  5. # 1.1 加载词表文件
  6. # 自动加载预训练模型(权重)
  7. # tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
  8. # 手动加载词表文件:gpt2-merges.txt gpt2-vocab.json。
  9. # from_pretrained方法是支持从本地载入多个词表文件的,但对载入的词表文件名称有特殊的要求:该文件名称必须按照源码文件tokenization_gpt2.py的VOCAB_FILES_NAMES字典对象中定义的名字来命名。
  10. # 故使用from_pretrained方法,必须对已经下载好的词表文件进行改名将/gpt2/gpt2-vocab.json和/gpt2/gpt2-merges.txt这两个文件,分别改名为“gpt2/vocab.json和/gpt2/merges.txt
  11. tokenizer = GPT2Tokenizer.from_pretrained(r'./models/gpt2') # 自动加载改名后的文件
  12. # 编码输入
  13. indexed_tokens = tokenizer.encode("Who is Li BiGor ? Li BiGor is a")
  14. print("输入语句为:",tokenizer.decode(indexed_tokens))
  15. tokens_tensor = torch.tensor([indexed_tokens]) # 将输入语句转换为张量
  16. # 自动加载预训练模型(权重)
  17. # model = GPT2LMHeadModel.from_pretrained('gpt2')
  18. # 手动加载:配置文件gpt2-config.json 与 权重文件pt2-pytorch_model.bin
  19. model = GPT2LMHeadModel.from_pretrained('./models/gpt2/gpt2-pytorch_model.bin',config='./models/gpt2/gpt2-config.json')
  20. # 将模型设置为评估模式
  21. model.eval()
  22. DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  23. tokens_tensor = tokens_tensor.to(DEVICE)
  24. model.to(DEVICE)
  25. # 预测所有标记
  26. with torch.no_grad():
  27. outputs = model(tokens_tensor)
  28. predictions = outputs[0]
  29. # 得到预测的下一词
  30. predicted_index = torch.argmax(predictions[0, -1, :]).item()
  31. predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])
  32. print("输出语句为:",predicted_text) # GPT-2模型没有为输入文本添加特殊词。
  33. # 输出:Who is Li BiGor? Li BiGor is a Chinese

2.2 代码实现:手动加载GPT-2模型并实现完整句子预测---GPT2_make.py(第2部分)

  1. # 案例描述:Transformers库中的GPT-2模型,通过循环生成下一词,实现将一句话补充完整。
  2. # 1.2 生成一段完整的话 这里有BUg 暂不会改
  3. stopids = tokenizer.convert_tokens_to_ids(["."])[0] # 定义结束符
  4. # 在循环调用模型预测功能时,使用了模型的past功能。该功能以使模型进入连续预测状态,即在前面预测结果的基础之上进行下一词预测,而不需要在每预测时,对所有句子进行重新处理。
  5. # past功能是使用预训练模型时很常用的功能,在Transformers库中,凡是带有下一词预测功能的预训练模型(如GPT,XLNet,CTRL等)都有这个功能。
  6. # 但并不是所有模型的past功能都是通过past参数进行设置的,有的模型虽然使用的参数名称是mems,但作用与pat参数一样。
  7. past = None # 定义模型参数
  8. for i in range(100): # 循环100次
  9. with torch.no_grad():
  10. output, past = model(tokens_tensor, past=past) # 预测下一次
  11. token = torch.argmax(output[..., -1, :])
  12. indexed_tokens += [token.tolist()] # 将预测结果收集
  13. if stopids == token.tolist(): # 当预测出句号时,终止预测。
  14. break
  15. tokens_tensor = token.unsqueeze(0) # 定义下一次预测的输入张量
  16. sequence = tokenizer.decode(indexed_tokens) # 进行字符串编码
  17. print(sequence)

3 GPT2_make.py(汇总)

  1. import torch
  2. from transformers import GPT2Tokenizer, GPT2LMHeadModel
  3. # 案例描述:Transformers库中的GPT-2模型,并用它实现下一词预测功能,即预测一个未完成句子的下一个可能出现的单词。
  4. # 下一词预测任务是一个常见的任务,在Transformers库中有很多模型都可以实现该任务。也可以使用BERT模型来实现。选用GPT-2模型,主要在于介绍手动加载多词表文件的特殊方式。
  5. # 1.1 加载词表文件
  6. # 自动加载预训练模型(权重)
  7. # tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
  8. # 手动加载词表文件:gpt2-merges.txt gpt2-vocab.json。
  9. # from_pretrained方法是支持从本地载入多个词表文件的,但对载入的词表文件名称有特殊的要求:该文件名称必须按照源码文件tokenization_gpt2.py的VOCAB_FILES_NAMES字典对象中定义的名字来命名。
  10. # 故使用from_pretrained方法,必须对已经下载好的词表文件进行改名将/gpt2/gpt2-vocab.json和/gpt2/gpt2-merges.txt这两个文件,分别改名为“gpt2/vocab.json和/gpt2/merges.txt
  11. tokenizer = GPT2Tokenizer.from_pretrained(r'./models/gpt2') # 自动加载改名后的文件
  12. # 编码输入
  13. indexed_tokens = tokenizer.encode("Who is Li BiGor ? Li BiGor is a")
  14. print("输入语句为:",tokenizer.decode(indexed_tokens))
  15. tokens_tensor = torch.tensor([indexed_tokens]) # 将输入语句转换为张量
  16. # 自动加载预训练模型(权重)
  17. # model = GPT2LMHeadModel.from_pretrained('gpt2')
  18. # 手动加载:配置文件gpt2-config.json 与 权重文件pt2-pytorch_model.bin
  19. model = GPT2LMHeadModel.from_pretrained('./models/gpt2/gpt2-pytorch_model.bin',config='./models/gpt2/gpt2-config.json')
  20. # 将模型设置为评估模式
  21. model.eval()
  22. DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  23. tokens_tensor = tokens_tensor.to(DEVICE)
  24. model.to(DEVICE)
  25. # 预测所有标记
  26. with torch.no_grad():
  27. outputs = model(tokens_tensor)
  28. predictions = outputs[0]
  29. # 得到预测的下一词
  30. predicted_index = torch.argmax(predictions[0, -1, :]).item()
  31. predicted_text = tokenizer.decode(indexed_tokens + [predicted_index])
  32. print("输出语句为:",predicted_text) # GPT-2模型没有为输入文本添加特殊词。
  33. # 输出:Who is Li BiGor? Li BiGor is a Chinese
  34. # 案例描述:Transformers库中的GPT-2模型,通过循环生成下一词,实现将一句话补充完整。
  35. # 1.2 生成一段完整的话 这里有BUg 暂不会改
  36. stopids = tokenizer.convert_tokens_to_ids(["."])[0] # 定义结束符
  37. # 在循环调用模型预测功能时,使用了模型的past功能。该功能以使模型进入连续预测状态,即在前面预测结果的基础之上进行下一词预测,而不需要在每预测时,对所有句子进行重新处理。
  38. # past功能是使用预训练模型时很常用的功能,在Transformers库中,凡是带有下一词预测功能的预训练模型(如GPT,XLNet,CTRL等)都有这个功能。
  39. # 但并不是所有模型的past功能都是通过past参数进行设置的,有的模型虽然使用的参数名称是mems,但作用与pat参数一样。
  40. past = None # 定义模型参数
  41. for i in range(100): # 循环100次
  42. with torch.no_grad():
  43. output, past = model(tokens_tensor, past=past) # 预测下一次
  44. token = torch.argmax(output[..., -1, :])
  45. indexed_tokens += [token.tolist()] # 将预测结果收集
  46. if stopids == token.tolist(): # 当预测出句号时,终止预测。
  47. break
  48. tokens_tensor = token.unsqueeze(0) # 定义下一次预测的输入张量
  49. sequence = tokenizer.decode(indexed_tokens) # 进行字符串编码
  50. print(sequence)

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

闽ICP备14008679号