【Python】科研代码学习:八 FineTune PretrainedModel (用 trainer,用 script);LLM文本生成

本文主要是介绍【Python】科研代码学习:八 FineTune PretrainedModel (用 trainer,用 script);LLM文本生成,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【Python】科研代码学习:八 FineTune PretrainedModel [用 trainer,用 script] LLM文本生成

  • 自己整理的 HF 库的核心关系图
  • 用 trainer 来微调一个预训练模型
  • 用 script 来做训练任务
  • 使用 LLM 做生成任务
    • 可能犯的错误,以及解决措施

自己整理的 HF 库的核心关系图

  • 根据前面几期,自己整理的核心库的使用/继承关系
    在这里插入图片描述

用 trainer 来微调一个预训练模型

  • HF官网API:FT a PretrainedModel
    今天讲讲FT训练相关的内容吧
    这里就先不提用 keras 或者 native PyTorch 微调,直接看一下用 trainer 微调的基本流程
  • 第一步:加载数据集和数据集预处理
    使用 datasets 进行加载 HF 数据集
from datasets import load_datasetdataset = load_dataset("yelp_review_full")

另外,需要用 tokenizer 进行分词。自定义分词函数,然后使用 dataset.map() 可以把数据集进行分词。

from transformers import AutoTokenizertokenizer = AutoTokenizer.from_pretrained("google-bert/bert-base-cased")def tokenize_function(examples):return tokenizer(examples["text"], padding="max_length", truncation=True)tokenized_datasets = dataset.map(tokenize_function, batched=True)

也可以先选择其中一小部分的数据单独拿出来,做测试或者其他任务

small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))
  • 第二步,加载模型,选择合适的 AutoModel 或者比如具体的 LlamaForCausalLM 等类。
    使用 model.from_pretrained() 加载
from transformers import AutoModelForSequenceClassificationmodel = AutoModelForSequenceClassification.from_pretrained("google-bert/bert-base-cased", num_labels=5)
  • 第三步,加载 / 创建训练参数 TrainingArguments
from transformers import TrainingArgumentstraining_args = TrainingArguments(output_dir="test_trainer")
  • 第四步,指定评估指标。trainer 在训练的时候不会去自动评估模型的性能/指标,所以需要自己提供一个
    ※ 这个 evaluate 之前漏了,放后面学,这里先摆一下 # TODO
import numpy as np
import evaluatemetric = evaluate.load("accuracy")
  • 第五步,使用 trainer 训练,提供之前你创建好的:
    model模型,args训练参数,train_dataset训练集,eval_dataset验证集,compute_metrics评估方法
trainer = Trainer(model=model,args=training_args,train_dataset=small_train_dataset,eval_dataset=small_eval_dataset,compute_metrics=compute_metrics,
)
trainer.train()
  • 完整代码,请替换其中的必要参数来是配置自己的模型和任务
from datasets import load_dataset
from transformers import (LlamaTokenizer,LlamaForCausalLM,TrainingArguments,Trainer,)
import numpy as np
import evaluatedef tokenize_function(examples):return tokenizer(examples["text"], padding="max_length", truncation=True)metric = evaluate.load("accuracy")
def compute_metrics(eval_pred):logits, labels = eval_predpredictions = np.argmax(logits, axis=-1)return metric.compute(predictions=predictions, references=labels)"""
Load dataset, tokenizer, model, training args
preprosess into tokenized dataset
split training dataset and eval dataset
"""
dataset = load_dataset("xxxxxxxxxxxxxxxxxxxx")tokenizer = LlamaTokenizer.from_pretrained("xxxxxxxxxxxxxxxxxxxxxxxxxx")
tokenized_datasets = dataset.map(tokenize_function, batched=True)small_train_dataset = tokenized_datasets["train"].shuffle(seed=42).select(range(1000))
small_eval_dataset = tokenized_datasets["test"].shuffle(seed=42).select(range(1000))model = LlamaForCausalLM.from_pretrained("xxxxxxxxxxxxxxx")training_args = TrainingArguments(output_dir="xxxxxxxxxxxxxx")"""
define metrics
set trainer and train
"""trainer = Trainer(model=model,args=training_args,train_dataset=small_train_dataset,eval_dataset=small_eval_dataset,compute_metrics=compute_metrics,
)trainer.train()

用 script 来做训练任务

  • 我们在很多项目中,都会看到启动脚本是一个 .sh 文件,一般里面可能会这么写:
python examples/pytorch/summarization/run_summarization.py \--model_name_or_path google-t5/t5-small \--do_train \--do_eval \--dataset_name cnn_dailymail \--dataset_config "3.0.0" \--source_prefix "summarize: " \--output_dir /tmp/tst-summarization \--per_device_train_batch_size=4 \--per_device_eval_batch_size=4 \--overwrite_output_dir \--predict_with_generate
  • 或者最近看到的一个
OUTPUT_DIR=${1:-"./alma-7b-dpo-ft"}
pairs=${2:-"de-en,cs-en,is-en,zh-en,ru-en,en-de,en-cs,en-is,en-zh,en-ru"}
export HF_DATASETS_CACHE=".cache/huggingface_cache/datasets"
export TRANSFORMERS_CACHE=".cache/models/"
# random port between 30000 and 50000
port=$(( RANDOM % (50000 - 30000 + 1 ) + 30000 ))accelerate launch --main_process_port ${port} --config_file configs/deepspeed_train_config_bf16.yaml \run_cpo_llmmt.py \--model_name_or_path haoranxu/ALMA-13B-Pretrain \--tokenizer_name haoranxu/ALMA-13B-Pretrain \--peft_model_id  haoranxu/ALMA-13B-Pretrain-LoRA \--cpo_scorer kiwi_xcomet \--cpo_beta 0.1 \--use_peft \--use_fast_tokenizer False \--cpo_data_path  haoranxu/ALMA-R-Preference \--do_train \--language_pairs ${pairs} \--low_cpu_mem_usage \--bf16 \--learning_rate 1e-4 \--weight_decay 0.01 \--gradient_accumulation_steps 1 \--lr_scheduler_type inverse_sqrt \--warmup_ratio 0.01 \--ignore_pad_token_for_loss \--ignore_prompt_token_for_loss \--per_device_train_batch_size 2 \--evaluation_strategy no \--save_strategy steps \--save_total_limit 1 \--logging_strategy steps \--logging_steps 0.05 \--output_dir ${OUTPUT_DIR} \--num_train_epochs 1 \--predict_with_generate \--prediction_loss_only \--max_new_tokens 256 \--max_source_length 256 \--seed 42 \--overwrite_output_dir \--report_to none \--overwrite_cache 
  • 玛雅,这么多 --xxx ,看着头疼,也不知道怎么搞出来这么多参数作为启动文件的。
    这种就是通过 script 启动任务了
  • github:transformers/examples
    看一下 HF github 给的一些任务的 examples 学习例子,就会发现
    main 函数中,会有这样的代码
    这个就是通过 argparser 来获取参数
    貌似还有 parserHfArgumentParser,这些都可以打包解析参数,又是挖个坑 # TODO
    这样的话,就可以通过 .sh 来在启动脚本中提供相关参数了
def main():parser = argparse.ArgumentParser()parser.add_argument("--model_type",default=None,type=str,required=True,help="Model type selected in the list: " + ", ".join(MODEL_CLASSES.keys()),)parser.add_argument("--model_name_or_path",default=None,type=str,required=True,help="Path to pre-trained model or shortcut name selected in the list: " + ", ".join(MODEL_CLASSES.keys()),)parser.add_argument("--prompt", type=str, default="")parser.add_argument("--length", type=int, default=20)parser.add_argument("--stop_token", type=str, default=None, help="Token at which text generation is stopped")# ....... 太长省略
  • 用脚本启动还有什么好处呢
    可以使用 accelerate launch run_summarization_no_trainer.py 进行加速训练
    再给 accelerate 挖个坑 # TODO
  • 所以,在 .sh script 启动脚本中具体能提供哪些参数,取决于这个入口 .py 文件的 parser 打包解析了哪些参数,然后再利用这些参数做些事情。

使用 LLM 做生成任务

  • HF官网API:Generation with LLMs
    官方都特地给这玩意儿单独开了一节,就说明其中有些很容易踩的坑…
  • 对于 CausalLM,首先看一下 next token 的生成逻辑:输入进行分词与嵌入后,通过多层网络,然后进入到一个LM头,最终获得下一个 token 的概率预测
  • 那么生成句子的逻辑,就是不断重复这个过程,获得 next token 概率预测后,通过一定的算法选择下一个 token,然后再重复该操作,就能生成整个句子了。
  • 那什么时候停止呢?要么是下一个token选择了 eos,要么是到达了之前定义的 max token length
    在这里插入图片描述
  • 接下来看一下代码逻辑
  • 第一步,加载模型
    device_map:控制模型加载在 GPUs上,不过一般我会使用 os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" 以及 os.environ["CUDA_VISIBLE_DEVICES"] = "1,2"
    load_in_4bit 设置加载量化
from transformers import AutoModelForCausalLMmodel = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", load_in_4bit=True
)
  • 第二步,加载分词器和分词
    记得分词的向量需要加载到 cuda
from transformers import AutoTokenizertokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to("cuda")
  • 但这个是否需要分词取决于特定的 model.generate() 方法的参数
    就比如 disc 模型的 generate() 方法的参数为:
    也就是说,我输入的 prompt 只用提供字符串即可,又不需要进行分词或者分词器了。
    在这里插入图片描述
  • 第三步,通常的 generate 方法,输入是 tokenized 后的数组,然后获得 ids 之后再 decode 变成对应的字符结果
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
  • 当然我也可以批处理,一次做多个操作,批处理需要设置pad_token
tokenizer.pad_token = tokenizer.eos_token  # Most LLMs don't have a pad token by default
model_inputs = tokenizer(["A list of colors: red, blue", "Portugal is"], return_tensors="pt", padding=True
).to("cuda")
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)

可能犯的错误,以及解决措施

  • 控制输出句子的长度
    需要在 generate 方法中提供 max_new_tokens 参数
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to("cuda")# By default, the output will contain up to 20 tokens
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]# Setting `max_new_tokens` allows you to control the maximum length
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
  • 生成策略修改
    有时候默认使用贪心策略来获取 next token,这个时候容易出问题(循环生成等),需要设置 do_sample=True
    在这里插入图片描述

  • pad 对齐方向
    如果输入不等长,那么会进行pad操作
    由于默认是右侧padding,而LLM在训练时没有学会从pad_token接下来的生成策略,所以会出问题
    所以需要设置 padding_side="left![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6084ff91d85c49e28a4faf498b8e5997.png) "
    在这里插入图片描述

  • 如果没有使用正确的 prompt(比如训练时的prompt格式),得到的结果就会不如预期
    (in one sitting = 一口气) (thug = 暴徒)
    这里需要参考 HF对话模型的模板 以及 HF LLM prompt 指引
    在这里插入图片描述
    比如说,QA的模板就像这样。
    更高级的还有 few shotCOT 技巧。

torch.manual_seed(4)
prompt = """Answer the question using the context below.
Context: Gazpacho is a cold soup and drink made of raw, blended vegetables. Most gazpacho includes stale bread, tomato, cucumbers, onion, bell peppers, garlic, olive oil, wine vinegar, water, and salt. Northern recipes often include cumin and/or pimentón (smoked sweet paprika). Traditionally, gazpacho was made by pounding the vegetables in a mortar with a pestle; this more laborious method is still sometimes used as it helps keep the gazpacho cool and avoids the foam and silky consistency of smoothie versions made in blenders or food processors.
Question: What modern tool is used to make gazpacho?
Answer:
"""sequences = pipe(prompt,max_new_tokens=10,do_sample=True,top_k=10,return_full_text = False,
)for seq in sequences:print(f"Result: {seq['generated_text']}")

这篇关于【Python】科研代码学习:八 FineTune PretrainedModel (用 trainer,用 script);LLM文本生成的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/802464

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]