【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来获取参数
貌似还有parser和HfArgumentParser,这些都可以打包解析参数,又是挖个坑 # 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 - 所以,在
.shscript 启动脚本中具体能提供哪些参数,取决于这个入口.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 "

-
如果没有使用正确的
prompt(比如训练时的prompt格式),得到的结果就会不如预期
(in one sitting = 一口气) (thug = 暴徒)
这里需要参考 HF对话模型的模板 以及 HF LLM prompt 指引

比如说,QA的模板就像这样。
更高级的还有few shot和COT技巧。
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文本生成
【Python】科研代码学习:八 FineTune PretrainedModel [用 trainer,用 script] LLM文本生成 自己整理的 HF 库的核心关系图用 trainer 来微调一个预训练模型用 script 来做训练任务使用 LLM 做生成任务可能犯的错误,以及解决措施 自己整理的 …...
SpringBoot RestTemplate远程调用总结
1、get请求 GetMapping("/searchEntryRecordPageList") public JSONObject searchEntryRecordPageList(RequestParam Map<String,Object> params){HttpHeaders requestHeaders new HttpHeaders();requestHeaders.add("Authorization","Bearer…...
Python 强大邮件处理库 Imbox
目录 IMAP Mailbox Imbox 安装 特性 提取邮件内容 处理附件 安全性 示例 1:读取收件箱中的邮件 2:搜索并下载附件 3:连接到IMAP服务器获取所有邮件 结论 IMAP Mailbox IMAP(Internet Message Access Protocol&#x…...
ElasticSearch深度分页问题如何解决
文章目录 概述解决方法深度分页方式from size深度分页之scrollsearch_after 三种分页方式比较 概述 Elasticsearch 的深度分页问题是指在大数据集上进行大量分页查询时可能导致的性能下降和资源消耗增加的情况。这种情况通常发生在需要访问大量数据的情形下,比如用…...
景安空间不支持指定运行目录tp5
/WEB/public/.htaccess配置 <IfModule mod_rewrite.c> Options FollowSymlinks -Multiviews RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php?s$1 [QSA,PT,L] </IfModule>. 2./WEB/.ht…...
开放式高实时高性能PLC控制器解决方案-基于米尔电子STM32MP135
前言 随着工业数字化进程加速与IT/OT深入融合,不断增加的OT核心数据已经逐步成为工业自动化行业的核心资产,而OT层数据具备高实时、高精度、冗余度高、数据量大等等特点,如何获取更加精准的OT数据对数字化进程起到至关重要的作用,…...
【MySQL】-MVCC多版本并发控制
1、当前读 select 不加锁状态,当前读快照读 2、快照读 在select加锁下,读取数据后,形成快照。每个事务都会形成自己的快照内容 SELECT * FROM xx_table LOCK IN SHARE MODE;SELECT * FROM xx_table FOR UPDATE;INSERT INTO xx_table ...D…...
mangoDB:2024安装
mangoDB:2024安装 mangoDB: 下载链接 取消勾选 配置环境变量 启动服务 同级目录下创建一个db文件夹 然后执行命令,启动服务 mongod --dbpath D:\environment\mango\db访问http://localhost:27017/ 出现下面的就是安装成功 2然后在管理员权限下给mango服务重…...
微服务day06-Docker
Docker 大型项目组件较多,运行环境也较为复杂,部署时会碰到一些问题: 依赖关系复杂,容易出现兼容性问题 开发、测试、生产环境有差异 1.什么是Docker? 大型项目组件很多,运行环境复杂,部署时会遇到各种…...
喜马拉雅后端一面
1.自我介绍 2.项目拷打 2.1 为什么要用分布式锁? 2.2 用唯一索引能不能保证一人一单,和你的分布式锁比起来怎么用? 2.3 分布式锁是在事务开启前加还是事务开始后 2.4 讲讲你的布隆过滤器是怎么自定义实现的 2.5 讲讲你的Redis和数据库的数据一…...
Open3D 生成空间3D椭圆点云
目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 设椭圆在 X O Y XOY XO...
huggingface快速下载
方法一:但是这个方法会卡主 pip install -U huggingface_hub pip install -U hf-transfer export HF_HUB_ENABLE_HF_TRANSFER1 (Linux,可以写入bashrc或zshrc) export HF_ENDPOINThttps://hf-mirror.com huggingface-cli dow…...
Java - Spring MVC 实现跨域资源 CORS 请求
据我所知道的是有三种方式:Tomcat 配置、拦截器设置响应头和使用 Spring MVC 4.2。 设置 Tomcat 这种方式就是引用别人封装好的两个 jar 包,配置一下web.xml就行了。我也并不推荐,这里放两个我在网上找到的配置相关文章,感兴趣可…...
宝妈做什么兼职副业好?适合她们的有哪些?执行力才是关键
现在的宝妈,生完孩子以后,尤其是宝宝上幼儿园之前,为了照顾宝宝,不能去外面上班,所以很多妈妈都为孩子做出了很大的牺牲,但同时又要承担着家庭经济的压力,尤其是现在注重个性独立的时代…...
RK3568 xhci主控挂死问题
串口日志 rootjenet:~# [18694.115430] xhci-hcd xhci-hcd.1.auto: xHCI host not responding to stop endpoint command. [18694.125667] xhci-hcd xhci-hcd.1.auto: xHCI host controller not responding, assume dead [18694.125977] xhci-hcd xhci-hcd.1.auto: HC died; c…...
CircuitBreaker断路器(服务熔断,服务降级)
分布式系统面临的问题: 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败。 1.服务雪崩 多个微服务之间调用的时候,假设微服务A调用微服务B和微服务C,微服务B和微服务C又调用其它的微服务ÿ…...
平面纯弯梁单元Matlab有限元编程 |欧拉梁单元| 简支梁|悬臂梁|弯矩图 |变形图| Matlab源码 | 视频教程
专栏导读 作者简介:工学博士,高级工程师,专注于工业软件算法研究本文已收录于专栏:《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现,并提供所有案例完整源码;2.单元…...
LeetCode_Hot100_栈_155最小栈_Python
题目 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。i…...
力扣每日一题 找出数组的第 K 大和 小根堆 逆向思维(TODO:二分+暴搜)
Problem: 2386. 找出数组的第 K 大和 文章目录 思路复杂度💖 小根堆💖 TODO:二分 暴搜 思路 👨🏫 灵神题解 复杂度 时间复杂度: 添加时间复杂度, 示例: O ( n ) O(n) O(n) 空间复杂度: 添加空间复杂…...
Git的介绍
导出项目依赖 # 以后项目给别人需要导出项目依赖,放在项目路径下,以后在运行项目前,先安装依赖 一般约定俗成都叫 requirements.txt,但是会有别的:req.txt | dev.txt # 两种方式: 1、虚拟环境所有装的第三方&…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
