当前位置:   article > 正文

(5-5-02)金融市场情绪分析:使用Llama 2 大模型实现财经信息的情感分析微调(2)_special tokens have been added in the vocabulary,

special tokens have been added in the vocabulary, make sure the associated w

5.5.4  Llama-2语言模型操作

编写下面的代码,功能是加载、配置 Llama-2 语言模型以及其对应的分词器,准备好模型为后续的对话生成任务做好准备。

  1. model_name = "../input/llama-2/pytorch/7b-hf/1"
  2. compute_dtype = getattr(torch, "float16")
  3. bnb_config = BitsAndBytesConfig(
  4. load_in_4bit=True,
  5. bnb_4bit_quant_type="nf4",
  6. bnb_4bit_compute_dtype=compute_dtype,
  7. bnb_4bit_use_double_quant=True,
  8. )
  9. model = AutoModelForCausalLM.from_pretrained(
  10. model_name,
  11. device_map=device,
  12. torch_dtype=compute_dtype,
  13. quantization_config=bnb_config,
  14. )
  15. model.config.use_cache = False
  16. model.config.pretraining_tp = 1
  17. tokenizer = AutoTokenizer.from_pretrained(model_name,
  18. trust_remote_code=True,
  19. )
  20. tokenizer.pad_token = tokenizer.eos_token
  21. tokenizer.padding_side = "right"
  22. model, tokenizer = setup_chat_format(model, tokenizer)

上述代码的实现流程如下:

(1)model_name = "../input/llama-2/pytorch/7b-hf/1":设置Llama-2 语言模型的路径。

(2)compute_dtype = getattr(torch, "float16"):从 Torch 库中获取 float16 数据类型,作为计算时的数据类型。

(3)创建了一个 BitsAndBytesConfig 对象 bnb_config,用于配置量化相关参数:

  1. load_in_4bit=True:以 4 位格式加载模型权重。
  2. bnb_4bit_quant_type="nf4":使用 "nf4" 量化类型。
  3. bnb_4bit_compute_dtype=compute_dtype:使用之前获取的 float16 数据类型进行计算。
  4. bnb_4bit_use_double_quant=True:使用双量化。

(4)使用 AutoModelForCausalLM.from_pretrained()方法加载预训练的 Llama-2 语言模型,并配置量化参数和设备信息。

(5)禁用模型的缓存,以确保每次预测都是基于最新的输入。

(6)将预训练令牌概率设置为1,以便模型在生成对话时保持更加开放的状态。

(7)使用 AutoTokenizer.from_pretrained()方法加载与模型对应的分词器,并配置填充相关参数。

(8)最后,调用 setup_chat_format() 函数来进一步配置模型和分词器的格式。

执行后会输出如下加载 Llama-2 语言模型过程中的进度信息,展示加载的进度和每个碎片加载所花费的时间。

Loading checkpoint shards: 100%2/2 [03:20<00:00, 91.76s/it]

5.5.5  情感标签预测

(1)编写函数 predict(test, model, tokenizer),功能是对测试数据进行情感标签的预测。通过这个函数,可以使用已加载的 Llama-2 模型对测试数据进行情感标签的预测,从而评估模型在情感分析任务上的性能。

  1. def predict(test, model, tokenizer):
  2. y_pred = []
  3. for i in tqdm(range(len(X_test))):
  4. prompt = X_test.iloc[i]["text"]
  5. pipe = pipeline(task="text-generation",
  6. model=model,
  7. tokenizer=tokenizer,
  8. max_new_tokens = 1,
  9. temperature = 0.0,
  10. )
  11. result = pipe(prompt)
  12. answer = result[0]['generated_text'].split("=")[-1]
  13. if "positive" in answer:
  14. y_pred.append("positive")
  15. elif "negative" in answer:
  16. y_pred.append("negative")
  17. elif "neutral" in answer:
  18. y_pred.append("neutral")
  19. else:
  20. y_pred.append("none")
  21. return y_pred
'
运行

在上述代码中,函数predict(test, model, tokenizer)会遍历测试数据集中的每个样本,并使用 Llama-2 模型生成一个新的令牌以预测对应的情感标签。具体步骤如下:

  1. 获取测试数据中的每个样本的提示文本。
  2. 使用 Hugging Face 的管道(pipeline)方法进行文本生成,以生成一个新的令牌。
  3. 从生成的文本中提取预测的情感标签。
  4. 将预测的情感标签添加到预测列表中。
  5. 返回预测的情感标签列表。

(2)调用前面定义的函数predict(),使用加载好的模型和分词器对测试数据进行情感标签的预测,并将预测结果存储在变量 y_pred 中。

y_pred = predict(test, model, tokenizer)

(3)调用前面定义的函数evaluate(),评估模型对测试数据的情感标签预测结果。

evaluate(y_true, y_pred)

函数evaluate()会计算模型的准确率、每个情感标签的准确率、生成分类报告和混淆矩阵,并打印输出这些评估结果。执行后会输出:

  1. Accuracy: 0.373
  2. Accuracy for label 0: 0.027
  3. Accuracy for label 1: 0.937
  4. Accuracy for label 2: 0.157
  5. Classification Report:
  6. precision recall f1-score support
  7. 0 0.89 0.03 0.05 300
  8. 1 0.34 0.94 0.50 300
  9. 2 0.67 0.16 0.25 300
  10. accuracy 0.37 900
  11. macro avg 0.63 0.37 0.27 900
  12. weighted avg 0.63 0.37 0.27 900
  13. Confusion Matrix:
  14. [[ 8 287 5]
  15. [ 1 281 18]
  16. [ 0 253 47]]

5.5.6  大模型微调(Fine-tuning)

(1)准备微调的设置李新喜,初始化了一个 Simple Fine-tuning Trainer (SFTTrainer) 对象用于微调模型。使用 Parameter-Efficient Fine-Tuning (PEFT) 方法训练大型语言模型,PEFT 方法旨在通过调整少量参数来微调模型,与完全微调整个模型相比,它能够节省时间并减少计算和存储开销。此外,PEFT 方法还可以缓解遗忘问题,这在完全微调语言模型时经常会发生。

  1. output_dir="trained_weigths"
  2. # 指定保存训练过程中模型权重和日志的目录。
  3. peft_config = LoraConfig(
  4. lora_alpha=16,
  5. lora_dropout=0.1,
  6. r=64,
  7. bias="none",
  8. target_modules="all-linear",
  9. task_type="CAUSAL_LM",
  10. )
  11. # 配置 PEFT 方法的参数,包括 LoRA 矩阵的学习率、dropout 等参数。
  12. training_arguments = TrainingArguments(
  13. output_dir=output_dir, # 保存训练日志和检查点的目录
  14. num_train_epochs=3, # 训练周期数
  15. per_device_train_batch_size=1, # 每个设备上每批样本数
  16. gradient_accumulation_steps=8, # 更新模型参数之前累积梯度的步数
  17. gradient_checkpointing=True, # 使用梯度检查点以节省内存
  18. optim="paged_adamw_32bit",
  19. save_steps=0,
  20. logging_steps=25, # 每 10 步记录一次训练指标
  21. learning_rate=2e-4, # 学习率,基于 QLoRA 论文
  22. weight_decay=0.001,
  23. fp16=True,
  24. bf16=False,
  25. max_grad_norm=0.3, # 最大梯度范数,基于 QLoRA 论文
  26. max_steps=-1,
  27. warmup_ratio=0.03, # 学习率预热比例,基于 QLoRA 论文
  28. group_by_length=True,
  29. lr_scheduler_type="cosine", # 使用余弦退火学习率调度器
  30. report_to="tensorboard", # 报告指标到 tensorboard
  31. evaluation_strategy="epoch" # 每个周期保存检查点
  32. )
  33. # 配置训练模型的参数,包括训练周期数、批次大小、学习率、梯度累积步数等。
  34. trainer = SFTTrainer(
  35. model=model,
  36. args=training_arguments,
  37. train_dataset=train_data,
  38. eval_dataset=eval_data,
  39. peft_config=peft_config,
  40. dataset_text_field="text",
  41. tokenizer=tokenizer,
  42. max_seq_length=1024,
  43. packing=False,
  44. dataset_kwargs={
  45. "add_special_tokens": False,
  46. "append_concat_token": False,
  47. }
  48. )
  49. # 初始化 SFTTrainer 对象,传入模型、训练参数、训练数据集、评估数据集、PEFT 配置等,并设置数据集参数。

# 初始化 SFTTrainer 对象,传入模型、训练参数、训练数据集、评估数据集、PEFT 配置等,并设置数据集参数。

(2)通过方法train()启动微调过程,即开始训练模型。通过调用此方法,模型将根据指定的训练参数(例如训练周期数、学习率、批次大小等)和训练数据集进行微调。在训练过程中,模型将逐步学习如何更好地适应特定的任务或数据集,以提高其性能。

trainer.train()

执行后会输出:

  1. You're using a LlamaTokenizerFast tokenizer. Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the text followed by a call to the `pad` method to get a padded encoding.
  2. [336/336 1:01:27, Epoch 2/3]
  3. Epoch Training Loss Validation Loss
  4. 0 0.802000 0.700182
  5. 2 0.516500 0.714122
  6. TrainOutput(global_step=336, training_loss=0.7176062436330886, metrics={'train_runtime': 3700.9349, 'train_samples_per_second': 0.73, 'train_steps_per_second': 0.091, 'total_flos': 1.0717884041527296e+16, 'train_loss': 0.7176062436330886, 'epoch': 2.99})

(3)通过下面的两行代码保存微调后的模型和分词器。其中trainer.save_model()用于保存微调后的模型到指定的输出目录,tokenizer.save_pretrained(output_dir)用于保存微调后的分词器到指定的输出目录。

  1. trainer.save_model()
  2. tokenizer.save_pretrained(output_dir)

执行后会输出:

  1. ('trained_weigths/tokenizer_config.json',
  2.  'trained_weigths/special_tokens_map.json',
  3.  'trained_weigths/tokenizer.model',
  4.  'trained_weigths/added_tokens.json',
  5.  'trained_weigths/tokenizer.json')

(4)启用TensorBoard 可视化工具,加载指定目录下的日志文件,以便在 TensorBoard 中查看训练过程中的指标和图表。

  1. %load_ext tensorboard
  2. %tensorboard --logdir logs/runs

TensorBoard 是 TensorFlow 提供的一个强大的可视化工具,可以帮助用户更直观地理解模型的训练情况。执行效果如图5-3所示,这是一个交互式图形的静态图像。要查看交互版本,请复制此内核并在编辑器中打开它。

图5-3  模型训练的可视化图

(5)释放内存和清理资源,避免内存泄漏和占用过多的系统资源。

  1. import gc
  2. del [model, tokenizer, peft_config, trainer, train_data, eval_data, bnb_config, training_arguments]
  3. del [df, X_train, X_eval]
  4. del [TrainingArguments, SFTTrainer, LoraConfig, BitsAndBytesConfig]
  5. for _ in range(100):
  6. torch.cuda.empty_cache()
  7. gc.collect()

对上述代码的具体说明如下所示:

  1. 删除之前创建的模型、分词器、PEFT 配置、训练器、训练数据集、评估数据集等对象,以释放它们所占用的内存。
  2. 删除pandas 数据框和其他变量,以释放它们占用的内存。
  3. 通过循环调用 torch.cuda.empty_cache()和 gc.collect()函数来清理 GPU 内存和 Python 垃圾回收,以确保释放的内存被彻底清理。

(6)执行下面的系统命令,用于在 NVIDIA GPU 系统上查看当前 GPU 的状态和使用情况。

!nvidia-smi

执行后会显示当前系统中所有 NVIDIA GPU 的详细信息,包括 GPU 的型号、显存使用情况、温度、驱动程序版本等信息。

  1. Sat Mar 23 22:52:36 2024
  2. +---------------------------------------------------------------------------------------+
  3. | NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |
  4. |-----------------------------------------+----------------------+----------------------+
  5. | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
  6. | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
  7. | | | MIG M. |
  8. |=========================================+======================+======================|
  9. | 0 Tesla P100-PCIE-16GB Off | 00000000:00:04.0 Off | 0 |
  10. | N/A 57C P0 41W / 250W | 1926MiB / 16384MiB | 0% Default |
  11. | | | N/A |
  12. +-----------------------------------------+----------------------+----------------------+
  13. +---------------------------------------------------------------------------------------+
  14. | Processes: |
  15. | GPU GI CI PID Type Process name GPU Memory |
  16. | ID ID Usage |
  17. |=======================================================================================|
  18. +---------------------------------------------------------------------------------------+

(7)加载微调后的模型,并通过 PEFT 库中的类AutoPeftModelForCausalLM实现自动加载和优化操作。然后,将加载的模型合并并保存到新的目录中,并保存了相应的分词器,以备后续使用。

  1. from peft import AutoPeftModelForCausalLM
  2. finetuned_model = "./trained_weigths/"
  3. compute_dtype = getattr(torch, "float16")
  4. tokenizer = AutoTokenizer.from_pretrained("/kaggle/input/llama-2/pytorch/7b-hf/1")
  5. model = AutoPeftModelForCausalLM.from_pretrained(
  6. finetuned_model,
  7. torch_dtype=compute_dtype,
  8. return_dict=False,
  9. low_cpu_mem_usage=True,
  10. device_map=device,
  11. )
  12. merged_model = model.merge_and_unload()
  13. merged_model.save_pretrained("./merged_model",safe_serialization=True, max_shard_size="2GB")
  14. tokenizer.save_pretrained("./merged_model")

执行后会输出:

  1. Loading checkpoint shards: 100%2/2 [00:05<00:00, 2.58s/it]
  2. Special tokens have been added in the vocabulary, make sure the associated word embeddings are fine-tuned or trained.
  3. ('./merged_model/tokenizer_config.json',
  4.  './merged_model/special_tokens_map.json',
  5.  './merged_model/tokenizer.model',
  6.  './merged_model/added_tokens.json',
  7.  './merged_model/tokenizer.json')

5.5.7  模型测试

(1)调用函数predict()对测试集进行预测,并使用函数evaluate()评估模型在测试集上的性能。函数predict()使用了合并后的模型 merged_model 和分词器 tokenizer 对测试集进行预测,并返回了预测结果 y_pred。然后,函数evaluate()利用真实标签 y_true 和预测标签 y_pred 对模型的性能进行评估,包括计算准确率、精确度、召回率等指标。

  1. y_pred = predict(test, merged_model, tokenizer)
  2. evaluate(y_true, y_pred)

执行后会输出:

  1. 100%|██████████| 900/900 [03:51<00:00, 3.89it/s]
  2. Accuracy: 0.847
  3. Accuracy for label 0: 0.890
  4. Accuracy for label 1: 0.870
  5. Accuracy for label 2: 0.780
  6. Classification Report:
  7. precision recall f1-score support
  8. 0 0.96 0.89 0.92 300
  9. 1 0.73 0.87 0.79 300
  10. 2 0.88 0.78 0.83 300
  11. accuracy 0.85 900
  12. macro avg 0.86 0.85 0.85 900
  13. weighted avg 0.86 0.85 0.85 900
  14. Confusion Matrix:
  15. [[267 31 2]
  16. [ 10 261 29]
  17. [ 1 65 234]]

(2)下面的这段代码将测试集中的文本、真实标签和预测标签组合成一个 DataFrame,并将其保存为 CSV 文件test_predictions.csv,以便后续分析和比较模型的预测结果。DataFrame 包括三列:'text' 列包含测试集中的文本,'y_true' 列包含真实的情感标签,'y_pred' 列包含模型预测的情感标签。CSV 文件中不包含行索引。

  1. evaluation = pd.DataFrame({'text': X_test["text"],
  2.                            'y_true':y_true,
  3.                            'y_pred': y_pred},
  4.                          )
  5. evaluation.to_csv("test_predictions.csv", index=False)

执行后可以比较微调后模型和基准模型(一个基于 CONV1D + 双向 LSTM 的模型)的评估结果,以确定微调后模型是否比基准模型更优秀。

  1. Accuracy: 0.623 Accuracy for label 0: 0.620 Accuracy for label 1: 0.590 Accuracy for label 2: 0.660
  2. Classification Report: precision recall f1-score support
  3. 0 0.79 0.62 0.69 300
  4. 1 0.61 0.59 0.60 300
  5. 2 0.53 0.66 0.59 300
  6. accuracy 0.62 900
  7. macro avg 0.64 0.62 0.63 900 weighted avg 0.64 0.62 0.63 900
  8. Confusion Matrix:
  9. [[186 39 75]\ [ 23 177 100]\ [ 27 75 198]]

本项目已完结:

(5-5-01)金融市场情绪分析:使用Llama 2 大模型实现财经信息的情感分析微调(1)-CSDN博客

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

闽ICP备14008679号