当前位置:   article > 正文

昇思25天学习打卡营第13天|LLM-基于MindSpore实现的GPT对话情绪识别

昇思25天学习打卡营第13天|LLM-基于MindSpore实现的GPT对话情绪识别

打卡

目录

打卡

预装环境

流程简述

部分执行结果演示

词向量加载过程

模型结构

模型训练过程

模型预测过程

代码


预装环境

  1. pip install -i https://pypi.mirrors.ustc.edu.cn/simple mindspore==2.2.14
  2. pip install mindnlp
  3. pip install jieba
  4. pip install spacy
  5. pip install ftfy

环境变量设置:HF_ENDPOINT=https://hf-mirror.com

流程简述

任务:用IMDB开源标注数据集,微调开源的预训练模型GPT,实现对话情绪识别。

1、数据集准备:IMDB数据集,从 https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/aclImdb_v1.tar.gz 下载数据集并按照7:3切分为训练和验证集。

2、加载TOKEN:用 mindnlp.transformers.GPTTokenizer 加载 tokenizer,并为其添加3个特殊的TOKEN("bos_token"、"eos_token"、"pad_token")

3、预处理训练、验证、测试数据集,包括将文本数据进行tokenizer,并根据设备类型对数据进行批处理和填充,其中训练集打散。

4、预训练模型微调设置:

  1. 用 mindnlp.transformers.GPTForSequenceClassification 加载预训练的 'openai-gpt' 模型,用于序列分类,配置指定模型的输出标签数量为2(通常是二分类任务)。
  2. 基于第二个步骤的 tokenzier,为预训练模型配置填充(padding)token ID。
  3.  为预训练模型配置调整token嵌入层的尺寸(+3,因为第二个步骤手动添加了3个特殊的TOKEN)。
  4. 定义模型优化器为 nn.Adam ,用于在训练过程中更新模型的参数,学习率设置为2e-5。
  5. 定义了一个准确率指标 ( metric=mindnlp._legacy.metrics.Accuracy() ),用于评估模型的性能。
  6. 定义2个回调函数,一个用于保存每个epoch的模型检查点,另一个用于保存最佳模型。

5、开始训练:创建训练器 (mindnlp._legacy.engine.Trainer)并训练,该训练器可以接收模型、训练数据集、评估数据集、评估指标、训练轮数、优化器、回调函数列表以及是否启用JIT编译的选项。

6、创建评估器并评估模型:创建评估器(mindnlp._legacy.engine.Evaluator),用于在测试数据集dataset_test上评估模型的性能。评估器使用了之前定义的预训练模型和评估指标metric

部分执行结果演示

词向量加载过程

看到词表大小为 40478,模型维度长512,右侧截断,一共有4种特殊的token.

模型结构

模型训练过程

loss降低到了0.2599,精度达到了 0.9421 。一般水平。 

模型预测过程

代码

  1. import os
  2. import numpy as np
  3. import mindspore
  4. from mindspore.dataset import text, GeneratorDataset, transforms
  5. from mindnlp.dataset import load_dataset
  6. from mindnlp.transformers import GPTTokenizer
  7. from mindspore import nn
  8. from mindnlp._legacy.engine import Trainer, Evaluator
  9. from mindnlp._legacy.engine.callbacks import CheckpointCallback, BestModelCallback
  10. from mindnlp._legacy.metrics import Accuracy
  11. from mindnlp.transformers import GPTForSequenceClassification
  12. from mindspore.experimental.optim import Adam
  13. def process_dataset(dataset, tokenizer, max_seq_len=512, batch_size=4, shuffle=False):
  14. """
  15. dataset: 待处理的数据集。
  16. tokenizer: 用于将文本转换为token的tokenizer对象.
  17. max_seq_len: 文本序列的最大长度,默认为512。
  18. batch_size: 批处理的大小,默认为4。
  19. shuffle: 是否对数据集进行随机打乱,默认为False。
  20. """
  21. ## 判断当前设备目标是否为Ascend(华为的昇腾处理器)。如果是,则is_ascend为True。
  22. is_ascend = mindspore.get_context('device_target') == 'Ascend'
  23. def tokenize(text):
  24. # 定义了一个内部函数tokenize,用于将文本转换为tokens。
  25. # 根据is_ascend的值来决定是否启用填充策略padding。函数返回token的input_ids和attention_mask。
  26. if is_ascend:
  27. tokenized = tokenizer(text, padding='max_length', truncation=True, max_length=max_seq_len)
  28. else:
  29. tokenized = tokenizer(text, truncation=True, max_length=max_seq_len)
  30. return tokenized['input_ids'], tokenized['attention_mask']
  31. if shuffle:
  32. ## shuffle参数为True,则对数据集进行打乱
  33. dataset = dataset.shuffle(batch_size)
  34. # map dataset
  35. ## 用map操作对数据集中的每个文本进行tokenization处理,将文本列text映射为input_ids和attention_mask。
  36. dataset = dataset.map(operations=[tokenize], input_columns="text", output_columns=['input_ids', 'attention_mask'])
  37. ## 将标签列label的数据类型转换为MindSpore的int32类型,并重命名为labels。
  38. dataset = dataset.map(operations=transforms.TypeCast(mindspore.int32), input_columns="label", output_columns="labels")
  39. #
  40. # batch dataset
  41. ## 根据设备类型将数据集分批处理。如果是在Ascend设备上,直接使用batch操作;否则,使用padded_batch操作来确保每个批次中的序列长度一致,不足部分使用pad token填充。
  42. if is_ascend:
  43. dataset = dataset.batch(batch_size)
  44. else:
  45. dataset = dataset.padded_batch(batch_size, pad_info={'input_ids': (None, tokenizer.pad_token_id),
  46. 'attention_mask': (None, 0)})
  47. return dataset
  48. imdb_ds = load_dataset('imdb', split=['train', 'test'])
  49. imdb_train = imdb_ds['train']
  50. imdb_test = imdb_ds['test']
  51. print("imdb_train data_size: ", imdb_train.get_dataset_size())
  52. print("imdb_test data_size: ", imdb_test.get_dataset_size())
  53. # tokenizer
  54. gpt_tokenizer = GPTTokenizer.from_pretrained('openai-gpt')
  55. print("openai-gpt GPTTokenizer: ", gpt_tokenizer)
  56. # add sepcial token: <PAD>
  57. special_tokens_dict = {
  58. "bos_token": "<bos>",
  59. "eos_token": "<eos>",
  60. "pad_token": "<pad>",
  61. }
  62. num_added_toks = gpt_tokenizer.add_special_tokens(special_tokens_dict)
  63. ## 训练集切分、处理
  64. # split train dataset into train and valid datasets
  65. imdb_train, imdb_val = imdb_train.split([0.7, 0.3])
  66. dataset_train = process_dataset(imdb_train, gpt_tokenizer, shuffle=True)
  67. dataset_val = process_dataset(imdb_val, gpt_tokenizer)
  68. dataset_test = process_dataset(imdb_test, gpt_tokenizer)
  69. ### 预训练模型加载
  70. # set bert config and define parameters for training
  71. model = GPTForSequenceClassification.from_pretrained('openai-gpt', num_labels=2)
  72. model.config.pad_token_id = gpt_tokenizer.pad_token_id
  73. model.resize_token_embeddings(model.config.vocab_size + 3)
  74. optimizer = nn.Adam(model.trainable_params(), learning_rate=2e-5)
  75. metric = Accuracy()
  76. # define callbacks to save checkpoints
  77. ckpoint_cb = CheckpointCallback(save_path='checkpoint', ckpt_name='gpt_imdb_finetune', epochs=1, keep_checkpoint_max=2)
  78. best_model_cb = BestModelCallback(save_path='checkpoint', ckpt_name='gpt_imdb_finetune_best', auto_load=True)
  79. trainer = Trainer(network=model, train_dataset=dataset_train,
  80. eval_dataset=dataset_train, metrics=metric,
  81. epochs=1, optimizer=optimizer, callbacks=[ckpoint_cb, best_model_cb],
  82. jit=False)
  83. ### 开始训练
  84. trainer.run(tgt_columns="labels")
  85. ### 开始评估
  86. evaluator = Evaluator(network=model, eval_dataset=dataset_test, metrics=metric)
  87. evaluator.run(tgt_columns="labels")

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

闽ICP备14008679号