精品欧美一区二区三区在线观看 _久久久久国色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)推薦
久久手机在线视频| 欧美/亚洲一区| 毛片不卡一区二区| 亚洲激情国产精品| 91精品免费视频| 在线免费观看日韩av| a级在线观看| 国产精品88久久久久久| 一本到不卡免费一区二区| 成人蜜桃视频| 国产av 一区二区三区| 日韩不卡在线| 久久综合色播五月| 午夜精品一区二区三区视频免费看| 中文av字幕在线观看| 成人在线免费看| 麻豆九一精品爱看视频在线观看免费| 欧美xfplay| 成人黄色片免费| 国产精品-色哟哟| 99久久99久久精品国产片果冰| 日韩欧美国产综合| 成人国产一区二区三区| 欧美在线观看在线观看| 亚洲欧美成人综合| 亚洲精品在线91| 国产情侣av自拍| 国产永久免费高清在线观看| 久久精品首页| 久久久久久网址| 天堂www中文在线资源| 黄色小说在线播放| a美女胸又www黄视频久久| 久久久欧美一区二区| 漂亮人妻被黑人久久精品| 伊人亚洲精品| 亚洲午夜影视影院在线观看| 国产一区二区三区四区五区在线| 日韩精品一区二区av| 狠狠久久伊人| 日本丶国产丶欧美色综合| 婷婷亚洲婷婷综合色香五月| 国产美女免费视频| 亚洲第一在线| 亚洲欧洲美洲在线综合| 日韩精品视频一二三| 26uuu亚洲电影在线观看| 成人avav在线| 国产精品综合网站| 欧美日韩在线视频免费| 全球av集中精品导航福利| 一本一道久久a久久精品综合蜜臀| 久久香蕉视频网站| 九七电影韩国女主播在线观看| 国产一区二区三区国产| 97av在线视频免费播放| www久久久久久久| 久久久久久爱| 欧美午夜美女看片| 伊人av成人| 欧美 日韩 国产 精品| 水野朝阳av一区二区三区| 久久久www成人免费精品张筱雨| www.黄色网| 欧美色片在线观看| 欧美综合色免费| 97碰在线视频| 91九色在线播放| 亚洲视频一二区| 欧美成人免费在线| 国产91免费在线观看| 日韩成人精品在线观看| 国内精品小视频在线观看| 国产乱码久久久久久| 国产欧美午夜| 欧美日韩国产123| 国产jk精品白丝av在线观看| 亚洲**毛片| 欧美亚洲动漫另类| 青青草精品视频在线| 日本福利专区在线观看| 久久久一区二区三区捆绑**| 91久久精品国产91久久性色tv| av一级在线观看| 亚洲伦理精品| 欧美激情高清视频| 成人18视频免费69| 免费精品国产的网站免费观看| 欧美一区二区日韩一区二区| 久久精品影视大全| 中文字幕人成乱码在线观看| 亚洲综合久久久| 亚洲综合激情五月| 午夜精品一区| 一区二区免费在线| 日本成人中文字幕在线| 精品一区二区三区中文字幕在线 | 不卡的av在线播放| 秋霞久久久久久一区二区| 亚洲av无码片一区二区三区 | 亚洲综合偷拍欧美一区色| 久久美女福利视频| caoporn视频在线| 欧美午夜精品久久久久久孕妇| 少妇欧美激情一区二区三区| 嫩草伊人久久精品少妇av杨幂| 制服丝袜中文字幕一区| 91亚洲免费视频| 国产成人一二片| 亚洲成人av片在线观看| 中文字幕55页| 亚州欧美在线| 777午夜精品免费视频| 久久性爱视频网站| 蜜桃一区av| www.99久久热国产日韩欧美.com| 99精品全国免费观看| 亚洲香蕉网站| 国产69精品久久久久99| 91亚洲欧美激情| 国产一区欧美日韩| 欧洲亚洲一区| 美女av在线免费看| 大桥未久av一区二区三区| 免费看欧美黑人毛片| 波多野结衣视频一区二区| 精品国产91久久久久久| 免费男同深夜夜行网站| 日韩一级二级| 亚洲精品suv精品一区二区| 欧美丰满熟妇bbbbbb| 蜜桃精品在线观看| 91久久嫩草影院一区二区| 视频二区在线| 亚洲国产精品99久久久久久久久| 一本一道久久a久久精品综合| 含羞草www国产在线视频| 91福利在线导航| 18禁裸乳无遮挡啪啪无码免费| 亚洲欧洲日本mm| 国产免费一区二区三区| 污片在线免费观看| 精品女同一区二区三区在线播放| 成人啪啪18免费游戏链接| 欧美日韩1区| 欧洲成人免费aa| 又色又爽又黄无遮挡的免费视频| 国产麻豆欧美日韩一区| 黑人另类av| a√资源在线| 亚洲第一搞黄网站| 九色porny自拍| 97偷自拍亚洲综合二区| 97在线免费观看视频| 蜜桃视频污在线观看| 亚洲成人www| 国产免费一区二区三区最新6| 精品成人久久| 久久草视频在线看| 麻豆tv在线| 欧美日韩性视频在线| 魔女鞋交玉足榨精调教| 巨乳诱惑日韩免费av| 日本精品一区二区三区视频 | 国产精品videossex久久发布| 99久久99| 95在线视频| 欧美人牲a欧美精品| 搡老熟女老女人一区二区| 香蕉久久网站| 秋霞成人午夜鲁丝一区二区三区| 人人九九精品| 欧美男女性生活在线直播观看| 一区二区三区少妇| 日本不卡一区二区三区| 国模一区二区三区私拍视频| 中文字幕色婷婷在线视频| 在线亚洲午夜片av大片| 中文字幕精品三级久久久| 国产精品一区二区男女羞羞无遮挡 | 久久av网址| 国产精品一区二区电影| 欧美xxxxhdvideosex| 欧美性大战xxxxx久久久| 亚洲精品久久久久久国| 久久在线精品| 一区二区三区在线视频看| 国产精品15p| 国产精品美腿一区在线看| 天堂√在线中文官网在线| 日韩欧美一区二区三区| 国产免费美女视频| 久久这里只有精品视频网| 色一情一区二区| 国内精品视频在线观看| 茄子视频成人在线| 麻豆传媒视频在线观看| 精品一区二区三区四区| 国产精品无码在线播放| 欧美性生交大片免费| 国产高潮流白浆| 久久综合九色综合97婷婷| 樱花草www在线| 久久精品一区| 日韩精品在线视频免费观看| 日韩免费在线| 成人在线播放av| 免费高清在线观看| 日韩av一区在线| 全部毛片永久免费看| 99免费精品在线| 亚洲精品在线视频播放| 老司机精品视频网站| 久久综合久久网| 91久久国产| 色狠狠久久av五月综合| 欧美重口另类| 国产一区二区无遮挡| 国产精品igao视频网网址不卡日韩| 日韩一二三在线视频播| 日夜干在线视频| 精品久久久久久亚洲综合网| 国产女人18毛片18精品| 色久综合一二码| 日韩美女黄色片| 一区二区三区四区不卡视频| 亚洲av人人澡人人爽人人夜夜| 精品亚洲国产成人av制服丝袜| 99热一区二区三区| 日韩成人三级| 天堂精品一区二区三区| 国产一区二区三区四区二区| 精品欧美国产| 好吊妞视频这里有精品 | 一区二区国产欧美| 欧美在线视频日韩| 无码人妻精品一区二区三区9厂 | 黄色污污视频软件| 97成人超碰视| 亚洲精品中文字幕无码蜜桃| 99热这里只有精品8| 日韩欧美99| 日韩黄色av| 91亚洲精品在线观看| 精品视频成人| 亚洲在线www| 波多野结衣久久精品| 最近2019中文字幕大全第二页 | 久国产精品韩国三级视频| 自拍偷拍视频在线| 久久精品亚洲人成影院| www.黄色网址.com| 免费精品一区二区三区在线观看| 国产日韩在线免费| 免费观看在线午夜影视| 日韩在线免费视频| 久久精品视频观看| 欧美成人免费网| 日韩一区二区三区不卡| 亚洲国产精品久久久久秋霞蜜臀| 色婷婷视频在线| 欧美日韩一区中文字幕| 91精品国产高潮对白| 亚洲国产成人tv| 无码人妻一区二区三区免费| 欧美专区在线观看一区| 国产精品毛片一区二区在线看舒淇| 日韩一区二区视频| 一区二区自拍偷拍| 午夜欧美2019年伦理| 欧美特黄一级片| 亚洲午夜精品一区二区三区他趣| 免费日韩一级片| 一区二区三区不卡视频在线观看| 国产亚洲色婷婷久久99精品| 中文字幕中文乱码欧美一区二区| 特级西西人体wwwww| 国产色产综合色产在线视频| 日本在线不卡一区二区| 91看片淫黄大片一级在线观看| 久久婷婷中文字幕| 裸体一区二区三区| 成人三级做爰av| 久久蜜桃av一区二区天堂| 制服丨自拍丨欧美丨动漫丨| 亚洲一卡二卡三卡四卡五卡| 日韩乱码一区二区三区| 精品国产一区二区在线观看| 国产视频在线观看视频| 精品99一区二区| chinese偷拍一区二区三区| 欧美国产在线视频| 欧美精品高清| 日本精品久久久久影院| 国产不卡123| 国产欧美精品日韩| 女同一区二区三区| 中文字幕一区二区三区最新 | 激情黄色小视频| av在线播放一区二区三区| 97在线观看免费高| 成人免费在线视频| 欧美福利在线视频| 国产精品网站在线播放| 精国产品一区二区三区a片| 一区二区三区日韩精品| 成人毛片一区二区三区| 精品999久久久| 黄色av免费在线| 国产精品美腿一区在线看| 小说区图片区色综合区| 欧洲亚洲一区二区| 在线精品一区| 成年人性生活视频| 最新国产精品久久精品| 黄色大全在线观看| 日韩精品视频中文在线观看| 亚洲精品一线| 亚洲一区二区三| 日韩精品不卡一区二区| 国产裸体舞一区二区三区| 成人久久视频在线观看| 亚洲av无码国产精品久久| 一区二区三区在线影院| 91福利在线观看视频| 一区二区成人精品| 国产日产一区二区| 国产精品免费一区| 精品国产一区二区三区久久久樱花| 亚洲制服欧美久久| 久久久久久久尹人综合网亚洲| 中文字幕免费高清视频| 午夜精品免费在线观看| 亚洲国产成人一区二区| 欧美精品在线免费| 日本一区影院| 欧美日韩中文字幕在线播放| 国产最新精品免费| 欧美偷拍第一页| 日韩一级大片在线| 日本一本在线免费福利| 9a蜜桃久久久久久免费| 欧美激情1区2区| 免费观看一区二区三区| 亚洲已满18点击进入久久| 好吊色一区二区三区| 97久久精品国产| 日韩伦理一区二区三区| 国产女女做受ⅹxx高潮| 久久蜜桃av一区精品变态类天堂| 91青青草视频| 色妞久久福利网| 欧美视频二区欧美影视| 日本手机在线视频| 91视频观看免费| 黄色av一级片| 欧美不卡激情三级在线观看| 69成人在线| 国产精品综合久久久久久| 国产精品99久久| 国产999免费视频| 午夜视频在线观看一区二区| 天堂a√在线| 国产欧美日韩中文| 欧美日韩综合| 亚洲制服丝袜在线播放| 亚洲美女少妇撒尿| 国产亚洲欧美在线精品| 国产一区二区三区四区福利| av资源新版天堂在线| 欧美日韩国产综合视频在线| 极品少妇一区二区三区| 国产精品成人99一区无码 | 精品自拍视频在线观看| 精品视频自拍| 午夜宅男在线视频| 亚洲永久免费视频| 欧美美乳在线| 久久久久久中文| 久久av影视| 中文字幕55页| 色综合天天综合在线视频| 日韩免费啪啪| 国产免费一区二区三区| 日本不卡一二三区黄网| 国产一级片播放| 日韩欧美一级在线播放| 亚洲欧美一区二区三区| 男女h黄动漫啪啪无遮挡软件| 不卡一卡二卡三乱码免费网站| 天天天天天天天干| 欧美激情网站在线观看| 精品国产一区探花在线观看| 国产精品嫩草69影院| 欧美少妇xxx| 亚洲性色av| 日韩一级特黄毛片| 亚洲国产精品99久久久久久久久| 好吊色视频一区二区| 成人网在线免费看|