精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

我們一起聊聊大模型 SFT 有監(jiān)督微調(diào)教程

發(fā)布于 2025-3-20 09:38
瀏覽
0收藏

開(kāi)源地址:???https://github.com/JieShenAI/csdn/tree/main/25/02/SFT???

我們一起聊聊大模型 SFT 有監(jiān)督微調(diào)教程-AI.x社區(qū)

??train.ipynb???:模型有監(jiān)督微調(diào)的代碼??infer.ipynb??: 模型訓(xùn)練完成后,進(jìn)行推理的代碼\

{
     'instruct': '請(qǐng)你給敖丙寫(xiě)一首詩(shī):', 
     'input': '碧海生龍子,云中舞雪霜。', 
     'label': '恩仇難兩忘,何處是家鄉(xiāng)?'
 }

預(yù)訓(xùn)練與有監(jiān)督微調(diào)對(duì)比 

我們一起聊聊大模型 SFT 有監(jiān)督微調(diào)教程-AI.x社區(qū)

兩者的訓(xùn)練數(shù)據(jù),大部分都一模一樣,維度在 label 部分,SFT 需要把指令部分的 label 設(shè)置為-100。

import json
from typing import List, Dict, Sequence
import torch
from torch.nn.utils.rnn import pad_sequence
import transformers
from transformers import TrainingArguments, Trainer, AutoModelForCausalLM, AutoTokenizer
from torch.utils.data import Dataset
from dataclasses import dataclass

IGNORE_INDEX = -100
device = "cuda:0"if torch.cuda.is_available() else"cpu"
model_dir = r"Qwen/Qwen2.5-0.5B"

model = AutoModelForCausalLM.from_pretrained(model_dir)
model = model.to("cuda:0")

tokenizer = AutoTokenizer.from_pretrained(model_dir, padding_side="right")

tokenizer.add_special_tokens({
    "pad_token": "[PAD]"
})

# 數(shù)據(jù)加載
with open("data.json.demo", "r") as f:
    data = json.load(f)

自定義數(shù)據(jù)集

class PreTrainDataset(Dataset):

    def __init__(self, data: List):
        super().__init__()
        self.data = data

    def __len__(self):
        return len(self.data)

    def __getitem__(self, idx) -> List[Dict]:
        item = self.data[idx]
        text = item["instruct"] + item["input"] + item["label"] + tokenizer.eos_token
        text_token = tokenizer(
            text,
            return_tensors="pt",
            padding="longest",
            max_length=tokenizer.model_max_length,
            truncatinotallow=True,
        )
        label = text_token["input_ids"].clone()

        instruct = item["instruct"] + item["input"]
        instruct_token = tokenizer(
            instruct,
            return_tensors="pt",
            padding="longest",
            max_length=tokenizer.model_max_length,
            truncatinotallow=True,
        )
        instruct_len = instruct_token["input_ids"].size(-1)

        label[:, :instruct_len] = -100
        text_token["labels"] = label
        return text_token


dataset = PreTrainDataset(data)
dataset[0]

因?yàn)?tokenizer 對(duì)文本進(jìn)行encode的時(shí)候,并不是一個(gè)詞一個(gè)token,會(huì)出現(xiàn)多個(gè)詞對(duì)應(yīng)一個(gè)token的情況。為了確定指令部分的token長(zhǎng)度,單獨(dú)對(duì)指令部分的文本計(jì)算一次的encode。然后使用切片 ??label[:, :instruct_len] = -100?? 把指令部分的 label 設(shè)置為 -100 不計(jì)算 loss。

查看第一個(gè)數(shù)據(jù):

# 查看第一個(gè)原始數(shù)據(jù)
data[0]

輸出:

{'instruct': '請(qǐng)你給哪吒寫(xiě)一首詩(shī):',
 'input': '哪吒降世,意氣飛揚(yáng)。\n逆天改命,破障沖霄。',
 'label': '紅綾纏腕,風(fēng)火踏浪。\n不屈不悔,笑傲蒼茫。'}

# 查看需要計(jì)算loss的文本
test_label = dataset[0][0]["label"]
test_label = test_label[test_label != -100]
tokenizer.decode(test_label)

輸出:

'紅綾纏腕,風(fēng)火踏浪。\n不屈不悔,笑傲蒼茫。<|endoftext|>'

# 查看label -100位置對(duì)應(yīng)的input_ids的文本
test_input_ids = dataset[0][0]["input_ids"]
test_label = dataset[0][0]["labels"]
test_input_ids = test_input_ids[test_label == -100]
tokenizer.decode(test_input_ids)
# label -100 位置的都是用戶的指令不參與 loss 計(jì)算

輸出:

'請(qǐng)你給哪吒寫(xiě)一首詩(shī):哪吒降世,意氣飛揚(yáng)。\n逆天改命,破障沖霄。'

DataCollatorForSFTDataset

下面是使用 ??pad_sequence?? 對(duì) tensor 進(jìn)行填充的一個(gè)示例。batch 放在第一個(gè)維度,用 0 進(jìn)行填充,在右邊進(jìn)行填充。

pad_sequence(
    [torch.randn(2), torch.randn(3), torch.randn(4)],
    batch_first=True,
    padding_value=0,
    padding_side="right",
)

輸出:

tensor([[-0.3421,  0.4131,  0.0000,  0.0000],
        [-0.1345,  1.2843,  1.0892,  0.0000],
        [-0.0567, -0.6993, -0.9386,  1.1316]])

使用 ??pad_sequence?? 在 DataCollatorForSFTDataset中,對(duì) tensor 進(jìn)行拼接與填充。

@dataclass
class DataCollatorForSFTDataset(object):
    tokenizer: transformers.PreTrainedTokenizer

    def __call__(self, items: Sequence) -> Dict[str, torch.Tensor]:
        # pad_sequence 不支持多維tensor,進(jìn)行維度壓縮 squeeze
        # input_ids, attention_mask = [
        #     [item.squeeze(0) for item in tokens[k]]
        #     for k in ["input_ids", "attention_mask"]
        # ]

        input_ids = [item["input_ids"].squeeze(0) for item in items]
        attention_mask = [item["attention_mask"].squeeze(0) for item in items]
        label = [item["label"].squeeze(0) for item in items]

        input_ids = pad_sequence(
            input_ids,
            batch_first=True,
            padding_value=tokenizer.pad_token_id,
            padding_side="right",
        )
        attention_mask = pad_sequence(
            attention_mask,
            batch_first=True,
            padding_value=0,
            padding_side="right",
        )
        label = pad_sequence(
            label,
            batch_first=True,
            padding_value=-100,
            padding_side="right",
        )

        return {
            "input_ids": input_ids,
            "attention_mask": attention_mask,
            "labels": label,
        }

注意: 在返回的字典中,要用 ??labels??? 而不是 ??label??。

驗(yàn)證一下,??DataCollatorForSFTDataset?? 的效果:

DataCollatorForSFTDataset(tokenizer=tokenizer)([dataset[0], dataset[1], dataset[2]])

模型訓(xùn)練

args = TrainingArguments(
    output_dir=r"C:\Users\1\Desktop\train_model_output\Qwen2.5-0.5B\SFT_output",
    num_train_epochs=10,
    per_device_train_batch_size=2,
    save_safetensors=True,
    logging_strategy="epoch",
)

??processing_class?? 是新參數(shù)名,使用舊參數(shù)名也可以:

trainer = Trainer(
    model=model,
    processing_class=tokenizer,
    args=args,
    train_dataset=dataset,
    eval_dataset=None,
    data_collator=DataCollatorForSFTDataset(tokenizer=tokenizer),
)

train_result = trainer.train()

我們一起聊聊大模型 SFT 有監(jiān)督微調(diào)教程-AI.x社區(qū)

查看模型訓(xùn)練的結(jié)果:

train_result.metrics

保存訓(xùn)練完成的模型:

trainer.save_state()
trainer.save_model(output_dir=args.output_dir)
tokenizer.save_pretrained(args.output_dir)

模型推理

看一下模型有監(jiān)督微調(diào)的效果。對(duì)比一下,預(yù)訓(xùn)練與有監(jiān)督微調(diào),模型在進(jìn)行推理的時(shí)候的區(qū)別:

  • 預(yù)訓(xùn)練的模型,對(duì)于輸入的文本都可以繼續(xù)續(xù)寫(xiě)出原文;
  • 有監(jiān)督微調(diào),只能根據(jù)指令寫(xiě)出對(duì)應(yīng)的答案;無(wú)法根據(jù)指令的前半部分,寫(xiě)出指令的后半部分:

instruct + label 作為指令部分,label 是指令的答案。若SFT微調(diào)后的大模型,輸入 instruct + label 能得到 label,說(shuō)明模型微調(diào)有效。當(dāng)給SFT微調(diào)后的大模型輸入instruct,模型應(yīng)該輸出label中的文本,但不能輸出input的文本,就能說(shuō)明label設(shè)置為-100,沒(méi)有計(jì)算指令部分loss。

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

device = "cuda:0"if torch.cuda.is_available() else"cpu"

train_model = r"C:\Users\1\Desktop\train_model_output\Qwen2.5-0.5B\SFT_output"

model = AutoModelForCausalLM.from_pretrained(train_model)
model = model.to(device)
tokenizer = AutoTokenizer.from_pretrained(train_model, padding_side="right")

tokenizer.add_special_tokens({"pad_token": "[PAD]"})

import json

with open("data.json", "r") as f:
    data =json.load(f)
data

def infer(text):
    input_ids = tokenizer(text, return_tensors="pt").to(model.device)

    generated_ids = model.generate(**input_ids)
    generated_ids = [
        output_ids[len(input_ids) :]
        for input_ids, output_ids in zip(input_ids.input_ids, generated_ids)
    ]

    response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
    return response

print("=" * 50 + "instruct" + "=" * 50)
for item in data:
    # instruct + input -> label
    instruct, input, label = item["instruct"], item["input"], item["label"]
    print(f"text_input: {instruct + input}")
    print(f"predict: {infer(instruct + input)}")
    print(f"label: {label}")
    print("-" * 101)

部分輸出結(jié)果:

text_input: 請(qǐng)你給哪吒寫(xiě)一首詩(shī):哪吒降世,意氣飛揚(yáng)。
逆天改命,破障沖霄。
predict: 紅綾纏腕,風(fēng)火踏浪。
不屈不悔,笑傲蒼茫。
label: 紅綾纏腕,風(fēng)火踏浪。
不屈不悔,笑傲蒼茫。

模型能夠根據(jù)指令,完成詩(shī)歌下半部分的寫(xiě)作。

print("=" * 50 + "instruct" + "=" * 50)
for item in data:
    # instruct + input -> label
    instruct, input, label = item["instruct"], item["input"], item["label"]
    print(f"text_input: {instruct }")
    print(f"predict: {infer(instruct)}")
    print(f"label: {label}")
    print("-" * 101)

部分輸出:

text_input: 請(qǐng)你給哪吒寫(xiě)一首詩(shī):
predict: 紅綾纏腕,風(fēng)火踏浪。不屈不悔,笑傲蒼茫。
label: 紅綾纏腕,風(fēng)火踏浪。
不屈不悔,笑傲蒼茫。

大模型只能輸出 label中的文本,模型不能輸出 input中的詩(shī)歌: ??哪吒降世,意氣飛揚(yáng)。逆天改命,破障沖霄。??這說(shuō)明模型沒(méi)有學(xué)到用戶指令部分的文本,這符合我們的預(yù)期。

本文轉(zhuǎn)載自??AI悠閑區(qū)??,作者:AI悠閑區(qū)


收藏
回復(fù)
舉報(bào)
回復(fù)
相關(guān)推薦
日韩精品中文字幕在线| 亚洲蜜臀av乱码久久精品蜜桃| 69视频在线免费观看| 少妇按摩一区二区三区| 国产一区二区精品调教| 爱情岛亚洲播放路线| 日韩国产欧美三级| 久久久国产精品视频| 亚洲中文字幕无码一区| 国产激情欧美| 天天综合天天综合色| 亚洲欧美在线网| 天堂av资源在线| 美女高潮久久久| 91精品国产免费久久久久久 | 91精品国产成人| 亚洲精品一区二区三区在线播放| 成午夜精品一区二区三区软件| 日本韩国欧美国产| 国产天堂视频在线观看| 日本电影全部在线观看网站视频| 成人免费毛片嘿嘿连载视频| 国产精品青青在线观看爽香蕉 | 含羞草www国产在线视频| 26uuu亚洲| 国产高清在线精品一区二区三区| 中文字幕日产av| 国产免费成人| 久久久欧美精品| 欧美日韩色视频| 精品理论电影在线| 日韩av中文字幕在线播放| 亚洲xxx在线观看| 欧美成人黑人| 精品久久久久国产| 日韩精品综合在线| 色呦呦网站在线观看| 亚洲欧洲国产专区| 日韩不卡av| 视频一区二区在线播放| 99re这里只有精品6| 成人在线免费网站| 精品人妻av一区二区三区| 久久91精品国产91久久小草| 国产精品黄视频| 国产精品乱码一区二区视频| 亚洲黄色免费| 91精品国产91久久久久福利| 国产午夜福利片| 欧美午夜一区| 欧美激情亚洲一区| 久久久久久美女| v8888av| 亚洲第一福利专区| 日韩久久免费视频| 全黄一级裸体片| 国产欧美高清视频在线| 精品偷拍一区二区三区在线看| 成人性生活免费看| 欧美在线导航| 亚洲欧美日韩国产成人| 久久精品成人av| 国产成人精品免费视| 亚洲欧美国产精品专区久久 | 亚洲男人的天堂网| 日韩视频在线免费观看| 国产精品无码一区二区三| 成人影院中文字幕| 亚洲国产成人91精品| 久久人人妻人人人人妻性色av| 国产精品自在| 亚洲老头同性xxxxx| 亚洲精品一区二区三区影院忠贞| 欧美日中文字幕| 日韩综合视频在线观看| 欧美精品入口蜜桃| 一本色道久久综合| 国产精品免费观看在线| 国产又粗又长视频| 成人精品一区二区三区中文字幕| 国产一区在线观| 国产香蕉在线| 亚洲欧美日韩国产成人精品影院 | 国产欧美二区| 国产精品福利观看| 精品人妻伦一二三区久久 | 在线播放欧美女士性生活| 91视频免费入口| 欧美顶级毛片在线播放| 中文日韩在线观看| 国产在线观看你懂的| 亚洲在线网站| 成人网在线视频| 天堂网在线中文| 国产精品入口麻豆九色| 免费在线黄网站| 日本高清不卡一区二区三区视频| 88在线观看91蜜桃国自产| 亚洲欧美日韩色| 精品久久久久中文字幕小说| 欧美国产乱视频| 欧美成人精品网站| 成人永久免费视频| 亚洲欧洲一区二区福利| gogo久久| 777奇米四色成人影色区| 国产熟妇搡bbbb搡bbbb| 亚洲激情中文| 国产精品福利网| 特黄视频在线观看| 亚洲另类一区二区| 91蝌蚪视频在线观看| 97人人澡人人爽91综合色| 伊人一区二区三区久久精品| 久久久久久国产精品免费播放| 日本不卡视频在线| 久久riav二区三区| 在线播放蜜桃麻豆| 欧美日韩精品免费| 精品成人av一区二区三区| 午夜久久美女| 亚洲一区二区三区sesese| 国产视频精品久久| 黄色91在线观看| 在线播放第一页| 亚洲欧美综合久久久| 国产精品视频午夜| 精品推荐蜜桃传媒| 欧美午夜激情小视频| 蜜桃色一区二区三区| 国产高清一区| 国产精品视频免费在线| 你懂的在线视频| 动漫精品一区二区| 99re这里只有| 日韩视频在线一区二区三区 | 国产精品久久久久一区二区国产| 亚洲电影中文字幕在线观看| 巨乳女教师的诱惑| 欧美电影免费观看高清| 国产精品丝袜白浆摸在线| 色视频在线看| 日韩欧美一区视频| 少妇大叫太粗太大爽一区二区| 999在线观看精品免费不卡网站| 动漫美女被爆操久久久| 污污视频在线| 精品国产制服丝袜高跟| 国产无遮挡又黄又爽又色| 成人久久18免费网站麻豆| 久艹视频在线免费观看| 精品综合久久88少妇激情| 国内成人精品视频| 无码国产色欲xxxx视频| 欧美色videos| av男人的天堂av| 免费观看久久久4p| 在线国产精品网| 亚洲一区二区三区四区电影| 久久久噜噜噜久久| 天堂资源中文在线| 91福利国产成人精品照片| 日本综合在线观看| 国产一区二区按摩在线观看| 91免费版看片| 牲欧美videos精品| 国产精品久久久久久久久久久新郎| 奇米影视888狠狠狠777不卡| 欧美色倩网站大全免费| 日韩在线观看免| 从欧美一区二区三区| 黄www在线观看| 欧美3p视频| 99久久伊人精品影院| 小视频免费在线观看| 夜夜躁日日躁狠狠久久88av| 97人妻精品一区二区三区软件| 一区二区三区资源| 久久午夜夜伦鲁鲁片| 日韩国产精品91| 奇米777四色影视在线看| 国产美女撒尿一区二区| 国产精品6699| 伊人春色在线观看| 亚洲精品视频二区| 91中文字幕在线播放| 亚洲网友自拍偷拍| 午夜在线观看一区| 成人一区二区三区| 在线看的黄色网址| 亚洲激情精品| 伊人色综合影院| 日韩中出av| 成人女保姆的销魂服务| 亚洲天堂手机| 九九九久久国产免费| 精品美女视频在线观看免费软件| 91精品国产综合久久福利软件| 日韩少妇裸体做爰视频| 中文字幕一区二区三区在线播放| 中文字幕在线视频播放| 激情综合网激情| 漂亮人妻被中出中文字幕| 一个色综合网| 午夜精品电影在线观看| 国产亚洲成av人片在线观黄桃| 国产精品综合久久久| 99热99re6国产在线播放| 日韩中文综合网| 全色精品综合影院| 欧美成人一区二区三区片免费 | 91精品久久久久久久91蜜桃| 99精品在线播放| 亚洲国产视频直播| 永久免费看片直接| 欧美高清在线一区| 日本一区二区三区网站| 成人网页在线观看| 黄色片免费网址| 乱一区二区av| www.超碰com| 国产日韩一区二区三区在线播放| 特级黄色录像片| 久久一级电影| 亚洲二区三区四区| 久久av免费| 九色综合日本| 九色丨蝌蚪丨成人| 99精品国产一区二区| 精品视频91| 成人免费自拍视频| 亚洲精品66| 国产伦精品免费视频| 成人四虎影院| 国产精品免费一区| 欧美xnxx| 国产精品福利网站| 91精品店在线| 国产精品视频yy9099| 成人亚洲免费| 国产精品福利小视频| 97精品国产99久久久久久免费| 日韩美女av在线免费观看| 亚洲风情在线资源| 日韩av免费在线观看| 日韩成人动漫| 国产精品第10页| 成人交换视频| 91天堂在线观看| 精品一区二区三区亚洲| 91九色露脸| 亚洲码欧美码一区二区三区| av在线不卡一区| 97久久综合精品久久久综合| 国产综合18久久久久久| 欧美久久精品| 日产精品一线二线三线芒果| 激情婷婷综合| 亚洲在线视频一区二区| 亚洲精品网址| 精品久久久久久无码中文野结衣| 亚洲激精日韩激精欧美精品| 免费一级特黄特色毛片久久看| 国产欧美丝祙| 三年中国国语在线播放免费| 蜜臀久久99精品久久久久久9| 亚洲最大天堂网| 国产精品一卡二卡在线观看| 一本色道久久hezyo无码| heyzo一本久久综合| 国产一二三四五区| 自拍偷在线精品自拍偷无码专区| 免费网站看av| 欧美性xxxx在线播放| 中文字幕一区2区3区| 日韩三级中文字幕| 青青草视频在线观看| 精品国偷自产在线视频99| 91av久久| 国产精品色婷婷视频| 亚洲精品一区二区三区在线| 欧美日韩精品综合| 久久精品影视| 97国产精东麻豆人妻电影| 麻豆精品一区二区三区| 亚洲女则毛耸耸bbw| 国产亚洲精久久久久久| 亚洲av无码一区二区三区在线| 五月婷婷综合激情| 中文字幕乱码中文字幕| 精品久久久久久亚洲综合网| 国产69久久| 久久久久久久国产精品视频| 97成人超碰| 欧美性猛交xxxx富婆| 久久爱av电影| 国产成人77亚洲精品www| 亚洲综合中文字幕在线| 久久av超碰| 日韩网站在线免费观看| 久久er99热精品一区二区| 少妇一级淫片免费放播放| 国产精品毛片久久久久久| 日本在线观看视频网站| 欧美日韩国产色站一区二区三区| 免费观看成年人视频| 俺去亚洲欧洲欧美日韩| 韩国成人漫画| 国产成人成网站在线播放青青| 欧美一级精品片在线看| 少妇高潮喷水在线观看| 国产伦精品一区二区三区免费迷 | 国产亚洲午夜高清国产拍精品| 欧美又粗又大又长| 欧美日韩一二三| 可以免费看污视频的网站在线| 久久99国产精品自在自在app| 久久天天久久| 欧美三日本三级少妇三99| 伊人久久亚洲美女图片| 91av免费观看| 亚洲精选视频在线| 中文字幕一区二区人妻痴汉电车| 精品夜色国产国偷在线| www.8ⅹ8ⅹ羞羞漫画在线看| 91在线视频九色| 97精品在线| 91看片在线免费观看| 久久久电影一区二区三区| 中文字幕激情小说| 亚洲精品久久久久久久久久久| 一二三四区在线观看| 亚洲最大福利网站| 91国语精品自产拍| 一级网站在线观看| 日韩理论片一区二区| 在线免费看91| 久久精品国产99国产精品澳门| 欧美激情福利| 中文字幕一区二区三区四区五区人| 久久国产剧场电影| 99久久精品久久亚洲精品| 欧美日韩黄视频| 免费黄色在线看| 91亚洲精品久久久久久久久久久久| 亚洲a在线视频| 99精品999| 亚洲免费在线视频| 91国内精品视频| 久久九九免费视频| 日韩第一区第二区| 国产免费一区二区视频| a在线欧美一区| 亚洲天堂av片| 国产一区二区三区三区在线观看 | 欧美日韩黄色一区二区| 久久bbxx| 91国产丝袜在线放| 精品成人在线| 亚洲午夜久久久久久久久红桃 | 成人av无码一区二区三区| 九九九久久国产免费| 久久99国产精品久久99大师| 欧美日韩黄色一级片| 国产无遮挡一区二区三区毛片日本| 人妻中文字幕一区二区三区| 久久精品国产69国产精品亚洲| 亚洲视频国产精品| 久久久久久久久久久视频| 国产午夜精品理论片a级大结局| 一区二区久久精品66国产精品| 欧美日韩国产成人在线| 亚洲另类春色校园小说| 午夜免费看毛片| 亚洲国产精品视频| 国产黄在线看| dy888夜精品国产专区| 久久精品首页| 69av.com| 亚洲天堂男人天堂女人天堂| 国产精品视频一区二区三区综合| 国产aaa免费视频| 国产精品天美传媒| 丰满肉嫩西川结衣av| 国产精品久久久久福利| 在线观看日韩| 18禁裸乳无遮挡啪啪无码免费| 欧美精品一二三区| 天堂av中文在线观看| 欧美日韩视频免费在线观看| 91香蕉视频污| 999久久久久久| 日韩av电影免费观看高清| 99久久国产综合精品成人影院| 熟女人妻在线视频| 欧美一级欧美三级在线观看| 国产日韩电影| 久久成人福利视频| 亚洲日本护士毛茸茸| 久青青在线观看视频国产|