自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

DeepSeek定制訓(xùn)練:微調(diào)與推理技術(shù)應(yīng)用

人工智能
本文檔描述了如何在MAC筆記本上對(duì)DeepSeek-R1-Distill-Llama-1.5BQwen架構(gòu)?進(jìn)行高效微調(diào),使用**?transformers進(jìn)行數(shù)據(jù)處理,并結(jié)合LoRA技術(shù)進(jìn)行模型微調(diào),使用WandB監(jiān)控訓(xùn)練過(guò)程,ModelScope下載模型。

一. 前言介紹

本文內(nèi)容:

  1. 模型加載與預(yù)處理:詳細(xì)講解如何加載預(yù)訓(xùn)練模型、分詞器,并處理輸入數(shù)據(jù)集。
  2. LoRA配置:介紹如何使用LoRA技術(shù)配置模型,并高效進(jìn)行微調(diào),節(jié)省計(jì)算資源。
  3. 訓(xùn)練過(guò)程:展示了如何配置訓(xùn)練參數(shù),使用SFTTrainer進(jìn)行訓(xùn)練,并通過(guò)WandB記錄訓(xùn)練日志。
  4. 模型保存與評(píng)估:如何保存微調(diào)后的模型,以及如何通過(guò)合適的評(píng)估集對(duì)模型進(jìn)行驗(yàn)證。
  5. 模型合并:展示了如何通過(guò)加權(quán)平均的方式合并多個(gè)模型權(quán)重,得到一個(gè)更強(qiáng)大的模型。

1.1 項(xiàng)目背景

本文檔描述了如何在MAC筆記本上對(duì)DeepSeek-R1-Distill-Llama-1.5BQwen架構(gòu) 進(jìn)行高效微調(diào),使用** transformers進(jìn)行數(shù)據(jù)處理,并結(jié)合LoRA技術(shù)進(jìn)行模型微調(diào),使用WandB監(jiān)控訓(xùn)練過(guò)程,ModelScope下載模型。(訓(xùn)練數(shù)據(jù)量大約2w條左右)

  • 由于為MAC筆記本本地訓(xùn)練 無(wú)顯卡支持 故而放棄(DeepSeek-R1-Distill-Qwen-7B Q wen)

下載的服務(wù)信息如下:

安裝服務(wù)

版本名稱(chēng)

作用

Unsloth


用于數(shù)據(jù)處理和模型微調(diào)。

Transformers


Hugging Face 提供的模型庫(kù),用于加載和微調(diào) DeepSeek-R1。

WandB


用于訓(xùn)練過(guò)程的實(shí)時(shí)監(jiān)控和可視化。

LoRA


用于微調(diào)的低秩適應(yīng)技術(shù)。

ModelScope


用于下載 DeepSeek-R1-8b 模型。

python3.11

Python 3.11

用于執(zhí)行 Python 腳本和訓(xùn)練任務(wù)。

1.2 LoRA和 QLoRA 簡(jiǎn)介

以下是 LoRA 和 QLoRA 的區(qū)別表格:

特性

LoRA (Low-Rank Adaptation)

QLoRA (Quantized LoRA)

核心原理

通過(guò)低秩矩陣分解減少需要調(diào)整的參數(shù)量

在 LoRA 的基礎(chǔ)上結(jié)合量化技術(shù),進(jìn)一步減少存儲(chǔ)和計(jì)算需求

主要優(yōu)點(diǎn)

降低訓(xùn)練時(shí)需要調(diào)整的參數(shù)數(shù)量,提高微調(diào)效率

除了低秩矩陣,還通過(guò)量化減少內(nèi)存占用,適用于資源有限的環(huán)境

存儲(chǔ)需求

較低,但不如 QLoRA 節(jié)省內(nèi)存

顯著減少內(nèi)存使用,適合在內(nèi)存受限的設(shè)備上使用

計(jì)算效率

提高訓(xùn)練效率,減少計(jì)算資源消耗

量化后的低精度計(jì)算進(jìn)一步提高了計(jì)算效率,降低了開(kāi)銷(xiāo)

適用場(chǎng)景

計(jì)算資源有限但不需要極限壓縮的場(chǎng)景

內(nèi)存和計(jì)算資源極其有限的環(huán)境,特別是在邊緣設(shè)備上使用

適用硬件

適用于大多數(shù)硬件設(shè)備,尤其是高性能計(jì)算環(huán)境

特別適合內(nèi)存有限的硬件,如邊緣設(shè)備、低內(nèi)存服務(wù)器等

1.3 LLaMA 架構(gòu)和 Qwen 架構(gòu)

特性

LLaMA 架構(gòu)

Qwen 架構(gòu)

開(kāi)發(fā)者

Meta(Facebook)

深度求索(DeepSeek)

設(shè)計(jì)目標(biāo)

高效、輕量化

中文優(yōu)化、多語(yǔ)言支持

參數(shù)量

7B、13B、33B、65B 等

7B、14B 等

開(kāi)源情況

開(kāi)源

部分開(kāi)源或未完全公開(kāi)

適用場(chǎng)景

資源有限的環(huán)境

中文任務(wù)、多語(yǔ)言任務(wù)

LLaMA 架構(gòu)

  • 全稱(chēng):Large Language Model Meta AI(LLaMA)
  • 開(kāi)發(fā)者:由 Meta(原 Facebook)開(kāi)發(fā)。
  • 特點(diǎn):

a.高效性:LLaMA 旨在以較少的參數(shù)量實(shí)現(xiàn)高性能,專(zhuān)注于優(yōu)化計(jì)算效率。

b.輕量化:模型參數(shù)量相對(duì)較?。ㄈ?7B、13B、33B、65B),但通過(guò)高質(zhì)量數(shù)據(jù)和訓(xùn)練方法,性能接近甚至超越更大的模型。

c.開(kāi)源:Meta 發(fā)布了 LLaMA 的權(quán)重和代碼,供研究社區(qū)使用。

  • 應(yīng)用場(chǎng)景:

a.適合資源有限的環(huán)境,如本地部署或移動(dòng)設(shè)備。

b.適用于各種 NLP 任務(wù),尤其是在生成、問(wèn)答、文本分類(lèi)等任務(wù)中,具有較好的性能和效率。

Qwen 架構(gòu)

  • 開(kāi)發(fā)者:由中國(guó)的深度求索(DeepSeek)團(tuán)隊(duì)開(kāi)發(fā)。
  • 特點(diǎn):

a.定制化設(shè)計(jì):Qwen 可能是針對(duì)中文或特定任務(wù)優(yōu)化的架構(gòu),具體細(xì)節(jié)未完全公開(kāi)。

b.多語(yǔ)言支持:Qwen 系列模型通常對(duì)中文有較好的支持,同時(shí)在英文和多語(yǔ)言任務(wù)上也有不錯(cuò)的表現(xiàn)。

c.參數(shù)量靈活:Qwen 系列包括不同規(guī)模的模型(如 7B、14B 等),適合不同場(chǎng)景。

  • 應(yīng)用場(chǎng)景:

Qwen 適用于文本生成、自動(dòng)化內(nèi)容創(chuàng)作、對(duì)話(huà)系統(tǒng)、語(yǔ)音合成等任務(wù)。

二. 環(huán)境準(zhǔn)備

2.1 Unsloth 安裝(顯卡版本-暫時(shí)不用)

  • Unsloth 是一個(gè)用于數(shù)據(jù)處理和模型微調(diào)的工具。您可以通過(guò)以下命令安裝:
  • MAC不試用,需要顯卡
##官網(wǎng):https://github.com/unslothai/unsloth

#01 創(chuàng)建項(xiàng)目,并設(shè)置python虛擬環(huán)境,python3.11版本

#02 安裝 unsloth(cpu版本)
brew install llvm(Homebrew clang version 19.1.7)
echo 'export PATH="/opt/homebrew/opt/llvm/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

pip install torch
pip install numpy
pip install"unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"



#03 版本檢查
python -c "import torch; print(torch.__version__)"
2.6.0

#04 引用
from unsloth import FastLanguageModel

安裝完成后,您可以使用 Unsloth 進(jìn)行數(shù)據(jù)的預(yù)處理、加載和微調(diào)模型。

  • 暫時(shí)不使用
#01 linux 服務(wù)建議使用docker


#02 拉取鏡像
docker pull modelscope-registry.us-west-1.cr.aliyuncs.com/modelscope-repo/modelscope:ubuntu22.04-py310-torch2.3.1-1.22.2

#03 啟動(dòng)

2.2 創(chuàng)建Python項(xiàng)目

#01 環(huán)境是python3.11

#02 項(xiàng)目目錄
Unsloth-DeepSeek-R1-8b/
├── data/                    # 存放訓(xùn)練數(shù)據(jù)、驗(yàn)證數(shù)據(jù)等
│   ├── raw/                 # 原始數(shù)據(jù)
│   └── processed/           # 預(yù)處理后的數(shù)據(jù)
│
├── models/                  # 存放模型文件
│   ├── checkpoints/         # 存儲(chǔ)訓(xùn)練過(guò)程中的模型檢查點(diǎn)
│   └── final_model/         # 存儲(chǔ)最終微調(diào)后的模型
│
├── scripts/                 # 存放訓(xùn)練腳本、數(shù)據(jù)處理腳本等
│   ├── train.py             # 訓(xùn)練腳本
│   ├── data_preprocessing.py# 數(shù)據(jù)預(yù)處理腳本
│   └── evaluate.py          # 評(píng)估腳本
│
├── logs/                    # 存放訓(xùn)練日志文件
│   └── training_logs.txt    # 訓(xùn)練過(guò)程中的日志
│
├── wandb/                   # 存放 wandb 相關(guān)的配置和記錄
│   └── wandb_config.py      # wandb 配置文件
│
├── environment/             # 環(huán)境配置文件
│   ├── requirements.txt     # 項(xiàng)目的 Python 依賴(lài)
│   └── environment.yml      # 如果使用 Conda,可以創(chuàng)建一個(gè)環(huán)境配置文件
│
├── main.py                  # 主運(yùn)行文件,啟動(dòng)訓(xùn)練或其他任務(wù)
└── README.md                # 項(xiàng)目的描述文件,包含如何使用和運(yùn)行的說(shuō)明


#03 創(chuàng)建目錄
# 創(chuàng)建子目錄
mkdir -p data/raw
mkdir -p data/processed
mkdir -p models/checkpoints
mkdir -p models/final_model
mkdir -p scripts
mkdir -p logs
mkdir -p wandb
mkdir -p environment

# 創(chuàng)建文件
touch scripts/train.py
touch scripts/data_preprocessing.py
touch scripts/evaluate.py
touch logs/training_logs.txt
touch wandb/wandb_config.py
touch environment/requirements.txt
touch environment/environment.yml
touch main.py
touch README.md

2.3 python 依賴(lài)庫(kù)

#03 安裝即可
pip install torch==2.6.0 transformers datasets

#03 更新證書(shū)(后續(xù)如果有pip網(wǎng)站使用https 會(huì)驗(yàn)證該證書(shū))
/Applications/Python\ 3.11/Install\ Certificates.command

2.4 LoRA peft 安裝

LoRA 和 PEFT 的安裝:

  • LoRA 和 PEFT 是用于高效微調(diào)的技術(shù)。如果你想在 Mac 上使用這些技術(shù)來(lái)微調(diào) DeepSeek 模型,你需要安裝相關(guān)的依賴(lài)項(xiàng)。
  • PEFT 包含了 LoRA 的實(shí)現(xiàn),并且它使得你能夠通過(guò)修改模型的一部分參數(shù)來(lái)進(jìn)行高效微調(diào),從而不需要調(diào)整整個(gè)模型的權(quán)重。
#01 安裝 peft
pip install peft

2.5 WandB 設(shè)置

WandB 是一個(gè)用于訓(xùn)練過(guò)程實(shí)時(shí)監(jiān)控和可視化的工具。您可以通過(guò)以下步驟設(shè)置 WandB:

  • 注冊(cè)并登錄 WandB官網(wǎng)。
  • 獲取您的 API 密鑰并配置環(huán)境變量:
#01 aipkey (本人谷歌郵箱)


#02 命令
pip install wandb
wandb login

#02  運(yùn)行文件
import wandb  # 導(dǎo)入 wandb 庫(kù),用于跟蹤和可視化實(shí)驗(yàn)
import random  # 導(dǎo)入 random 庫(kù),用于生成隨機(jī)數(shù)

# 開(kāi)始一個(gè)新的 wandb 運(yùn)行來(lái)跟蹤當(dāng)前腳本
wandb.init(
    # 設(shè)置 wandb 項(xiàng)目,所有與該運(yùn)行相關(guān)的數(shù)據(jù)將被記錄到這個(gè)項(xiàng)目中
    project="my-awesome-project",  # 項(xiàng)目名稱(chēng),你可以在 wandb 儀表盤(pán)中看到這個(gè)項(xiàng)目
    
    # 追蹤超參數(shù)和運(yùn)行的元數(shù)據(jù)
    config={
        "learning_rate": 0.02,  # 設(shè)置學(xué)習(xí)率
        "architecture": "CNN",  # 模型架構(gòu)(這里是卷積神經(jīng)網(wǎng)絡(luò))
        "dataset": "CIFAR-100",  # 使用的數(shù)據(jù)集(這里是 CIFAR-100 數(shù)據(jù)集)
        "epochs": 10,  # 訓(xùn)練的輪數(shù)
    }
)

# 模擬訓(xùn)練過(guò)程
epochs = 10# 總訓(xùn)練輪數(shù)
offset = random.random() / 5# 生成一個(gè)小的隨機(jī)偏移量,用于模擬訓(xùn)練過(guò)程中一些不確定性

# 開(kāi)始訓(xùn)練循環(huán),模擬 2 到 10 輪的訓(xùn)練過(guò)程
for epoch inrange(2, epochs):  # 從第二輪開(kāi)始,到第 10 輪結(jié)束
    # 模擬準(zhǔn)確率的變化,隨著 epoch 的增加,準(zhǔn)確率逐漸提升
    acc = 1 - 2 ** -epoch - random.random() / epoch - offset
    
    # 模擬損失的變化,隨著 epoch 的增加,損失逐漸減少
    loss = 2 ** -epoch + random.random() / epoch + offset

    # 使用 wandb 記錄每一輪的準(zhǔn)確率(acc)和損失值(loss)
    wandb.log({"acc": acc, "loss": loss})

# [可選] 結(jié)束 wandb 運(yùn)行,確保數(shù)據(jù)被正確上傳并完成記錄
wandb.finish()

2.6 modelscope pull 模型

#01 安裝modelscope 
pip install modelscope

#02 下載模型文件
mkdir -p ./models/DeepSeek-R1-Distill-Llama-8B
mkdir -p ./models/DeepSeek-R1-Distill-Qwen-1.5B
mkdir -p ./models/DeepSeek-R1-Distill-Qwen-7B

modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Llama-8B --local_dir ./models/DeepSeek-R1-Distill-Llama-8B

modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B --local_dir ./models/DeepSeek-R1-Distill-Qwen-1.5B

modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local_dir ./models/DeepSeek-R1-Distill-Qwen-7B



modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Llama-8B --local_dir ./DeepSeek-R1-Distill-Llama-8B

2.7 測(cè)試模型使用

"""


訓(xùn)練前詢(xún)問(wèn)問(wèn)題:
  皮質(zhì)醇增多癥患者在血漿ACTH明顯升高且大劑量地塞米松抑制試驗(yàn)陽(yáng)性的情況下,應(yīng)考慮哪種疾?。?  
訓(xùn)練后再次詢(xún)問(wèn):


scripts/test_inference.py

"""


import os
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 獲取當(dāng)前腳本的路徑
current_dir = os.path.dirname(__file__)

# 拼接模型和分詞器路徑
model_dir = os.path.join(current_dir, '..', 'models', 'DeepSeek-R1-Distill-Qwen-1.5B')

# 打印路徑確認(rèn)
print(f"Model path: {model_dir}")

# 確保模型和分詞器的路徑存在
ifnot os.path.exists(model_dir):
    raise ValueError(f"Model directory does not exist at {model_dir}")
else:
    print("Model directory exists, proceeding with loading.")

# 加載模型和分詞器
print("Loading model and tokenizer...")
model = AutoModelForCausalLM.from_pretrained(model_dir)
tokenizer = AutoTokenizer.from_pretrained(model_dir)

# 打印模型和分詞器的配置信息
print(f"Model config: {model.config}")
print(f"Tokenizer config: {tokenizer}")

# 輸入中文文本
input_text = "皮質(zhì)醇增多癥患者在血漿ACTH明顯升高且大劑量地塞米松抑制試驗(yàn)陽(yáng)性的情況下,應(yīng)考慮哪種疾?。?
print(f"User input: {input_text}")

# 結(jié)構(gòu)化的 prompt
prompt_style_chat = f"""請(qǐng)寫(xiě)出一個(gè)恰當(dāng)?shù)幕卮饋?lái)完成當(dāng)前對(duì)話(huà)任務(wù)。

### Instruction:
你是一名助人為樂(lè)的助手。

### Question:
{input_text}

### Response:
<think>"""

# 使用分詞器處理輸入文本
inputs = tokenizer(prompt_style_chat, return_tensors="pt", padding=True, truncation=True, max_length=512)

# 打印 tokenized 輸入
print(f"Tokenized input: {inputs}")

# 打印輸入形狀
print(f"Input shape: {inputs['input_ids'].shape}")

# 打印模型的最大長(zhǎng)度
print(f"Model max length: {model.config.max_position_embeddings}")

# 將模型移至正確的設(shè)備(使用 GPU 如果可用)
device = "cuda"if torch.cuda.is_available() else"cpu"
model.to(device)

# 打印設(shè)備信息
print(f"Using device: {device}")

# 打印分詞器的 pad_token_id
pad_token_id = tokenizer.pad_token_id if tokenizer.pad_token_id isnotNoneelse model.config.pad_token_id
print(f"Using pad_token_id: {pad_token_id}")

# 生成模型輸出
print("Generating response...")
# 使用 max_new_tokens 來(lái)控制生成長(zhǎng)度
with torch.no_grad():  # 禁用梯度計(jì)算,節(jié)省內(nèi)存
    try:
        print("Calling model.generate()...")
        outputs = model.generate(
            inputs['input_ids'].to(device),
            attention_mask=inputs['attention_mask'].to(device),
            max_new_tokens=1200,  # 設(shè)置最大生成的 token 數(shù)量
            temperature=1.0,
            top_p=0.9,
            pad_token_id=pad_token_id
        )

        print("Model.generate() completed.")
    except Exception as e:
        print(f"Error generating response: {e}")
        raise

# 打印生成的輸出 ID 和它們的形狀
print(f"Generated output IDs: {outputs}")
print(f"Shape of generated output: {outputs.shape}")

# 解碼生成的輸出文本
try:
    response = tokenizer.decode(outputs[0], skip_special_tokens=True)
    print(f"Generated response: {response}")
except Exception as e:
    print(f"Error decoding output: {e}")
  • 問(wèn)題回答
User input:皮質(zhì)醇增多癥患者在血漿ACTH明顯升高且大劑量地塞米松抑制試驗(yàn)陽(yáng)性的情況下,應(yīng)考慮哪種疾???
Tokenized input: {'input_ids':tensor([[151646,  14880, 112672,  46944, 112449, 111423,  36407,  60548,  67949,
         105051,  88802,   3407,  14374,  29051,    510,  56568, 110124,  99262,
         103247,  99350,   9370, 110498,   3407,  14374,  15846,    510,  99888,
          99178, 103032, 107284,  99769, 101924,  18493,  99389, 101498,   6823,
             39, 100687, 109061, 100136,  26288, 114786,  29490, 101202,  72261,
         100180, 106555, 102360, 112758, 104248,   3837,  50511, 101118, 113195,
         101160,  26850,  14374,   5949,    510, 151648]]), 'attention_mask':tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])}
Input shape:torch.Size([1,60])
Model max length:131072
Using device:cpu
Using pad_token_id:151643
Generatingresponse...
Callingmodel.generate()...
Model.generate()completed.

Generated response:請(qǐng)寫(xiě)出一個(gè)恰當(dāng)?shù)幕卮饋?lái)完成當(dāng)前對(duì)話(huà)任務(wù)。

### Instruction:
你是一名助人為樂(lè)的助手。

### Question:
皮質(zhì)醇增多癥患者在血漿ACTH明顯升高且大劑量地塞米松抑制試驗(yàn)陽(yáng)性的情況下,應(yīng)考慮哪種疾病?

### Response:
<think>
好的,我現(xiàn)在需要仔細(xì)分析這個(gè)問(wèn)題并給出一個(gè)合適的回答。首先,問(wèn)題描述的是皮質(zhì)醇增多癥(PHT)患者在血漿ACTH明顯升高且大劑量地塞米松抑制試驗(yàn)(SSDS)顯示陽(yáng)性的情況下,應(yīng)考慮哪種疾病。

首先,我記得皮質(zhì)醇增多癥是由于皮質(zhì)醇分泌異常導(dǎo)致,通常由代謝紊亂或神經(jīng)退行性疾病引起,比如皮質(zhì)醇過(guò)激釋放癥、皮質(zhì)醇過(guò)激釋放性代謝綜合征等。通常,患者可能表現(xiàn)出皮質(zhì)醇水平升高,血漿ACTH顯著升高,這符合題意的第一個(gè)條件。

接下來(lái),第二個(gè)條件是SSDS試驗(yàn)陽(yáng)性。SSDS試驗(yàn)主要用于檢測(cè)皮質(zhì)醇釋放的細(xì)胞因子,比如PD-L1,這些因子在疾病早期有顯著的表觀(guān)變化。皮質(zhì)醇增多癥患者的皮質(zhì)醇釋放確實(shí)受阻,導(dǎo)致細(xì)胞因子釋放減少,這在SSDS中會(huì)被檢測(cè)出來(lái),所以這種情況屬于皮質(zhì)醇增多癥。

綜合這兩個(gè)條件,患者的血漿ACTH升高和SSDS陽(yáng)性,符合皮質(zhì)醇增多癥的特征。因此,這種情況下應(yīng)考慮的是皮質(zhì)醇增多癥。

我需要確保我沒(méi)有遺漏其他可能導(dǎo)致SSDS試驗(yàn)陽(yáng)性的情況。比如,是否有一些其他類(lèi)型的疾病,比如胰島素素合成障礙或胰島素缺乏,也會(huì)影響皮質(zhì)醇釋放?不過(guò),這些更可能是胰島素素合成障礙,而不是直接由皮質(zhì)醇釋放受阻引起的。皮質(zhì)醇增多癥通常是由于皮質(zhì)醇釋放異常,因此SSDS陽(yáng)性更直接與皮質(zhì)醇釋放受阻相關(guān)。

此外,ACTH升高可能與皮質(zhì)醇增多癥不同,而更可能是由于激素分泌過(guò)量或其他激素調(diào)節(jié)問(wèn)題。因此,ACTH升高的信號(hào)應(yīng)該更多指向皮質(zhì)醇增多癥。

綜上所述,這種情況下應(yīng)該考慮的疾病是皮質(zhì)醇增多癥。
</think>

應(yīng)考慮皮質(zhì)醇增多癥(PantoprazolidonePhenomenon)。

因?yàn)椋?
1.血漿ACTH顯著升高,符合皮質(zhì)醇增多癥的特征。
2.SSDS試驗(yàn)陽(yáng)性,表明皮質(zhì)醇釋放受阻,屬于皮質(zhì)醇增多癥的表現(xiàn)。

三. 訓(xùn)練數(shù)據(jù)數(shù)據(jù)

3.1 準(zhǔn)備數(shù)據(jù)集

#01 我們使用COT格式 醫(yī)學(xué)領(lǐng)域 medical-o1-reasoning-SFT 數(shù)據(jù)集
https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT

#02 b本地導(dǎo)入方式()
from datasets import load_dataset
ds = load_dataset("FreedomIntelligence/medical-o1-reasoning-SFT", "zh")
  • Hugging face 數(shù)據(jù)集
  • modelscope
#01 使用modelscope 數(shù)據(jù)集 官網(wǎng)地址
https://www.modelscope.cn/datasets/YIRONGCHEN/PsyDTCorpus/files

#02 下載完整數(shù)據(jù)集repo
modelscope download --dataset YIRONGCHEN/PsyDTCorpus --local_dir ./dir


#03 下載單個(gè)文件到指定本地文件夾(以下載README.md到當(dāng)前路徑下“dir”目錄為例)
modelscope download --dataset YIRONGCHEN/PsyDTCorpus README.md --local_dir ./dir

3.2 數(shù)據(jù)清洗

#01 用于對(duì)medical-o1-reasoning-SFT數(shù)據(jù)集進(jìn)行修改,Complex_CoT列和Response列進(jìn)行拼接,并加上文本結(jié)束標(biāo)記:
defformatting_prompts_func(examples, EOS_TOKEN):
    """
    格式化數(shù)據(jù)集中的每個(gè)示例,使其符合訓(xùn)練的要求。

    Args:
        examples (dict): 數(shù)據(jù)集中的輸入示例
        EOS_TOKEN (str): 結(jié)束符

    Returns:
        dict: 格式化后的文本數(shù)據(jù)
    """
    train_prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context. 
    Write a response that appropriately completes the request. 
    Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

    ### Instruction:
    You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning. 
    Please answer the following medical question. 

    ### Question:
    {}

    ### Response:
    <think>
    {}
    </think>
    {}"""

    inputs = examples["Question"]
    cots = examples["Complex_CoT"]
    outputs = examples["Response"]
    texts = []
    forinput, cot, output inzip(inputs, cots, outputs):
        text = train_prompt_style.format(input, cot, output) + EOS_TOKEN
        texts.append(text)
    return {"text": texts}



"""

問(wèn)題({}) 被嵌套到 ### Question: 下面,替換掉 {}。
推理過(guò)程({}) 被嵌套到 <think></think> 標(biāo)簽內(nèi),替換掉第二個(gè) {}。
答案({}) 被嵌套到模板的最后,替換掉第三個(gè) {}。
具體替換流程:
{} 第一個(gè)位置將會(huì)被每個(gè)樣本中的問(wèn)題(examples["Question"])替換。
{} 第二個(gè)位置將會(huì)被每個(gè)樣本中的推理過(guò)程(examples["Complex_CoT"])替換。
{} 第三個(gè)位置將會(huì)被每個(gè)樣本中的答案(examples["Response"])替換。
例如,如果輸入數(shù)據(jù)如下:

問(wèn)題(Question): "What is the cause of fever?"
推理過(guò)程(Complex_CoT): "Fever is usually caused by an infection or inflammation. We need to identify the source."
答案(Response): "The most common causes of fever are bacterial or viral infections."

"""
  • 原數(shù)據(jù)格式
{
    "Question": [
        "What is the cause of headache?",
        "How do you treat a cold?"
    ],
    "Complex_CoT": [
        "The causes of headaches are numerous, including tension, dehydration, or sinus issues.",
        "Treating a cold typically involves rest, fluids, and over-the-counter medications for symptoms."
    ],
    "Response": [
        "A headache can be caused by stress, lack of sleep, or a sinus infection.",
        "For a cold, hydration and rest are key. Medications like ibuprofen can help with symptoms."
    ]
}
  • 格式化后數(shù)據(jù)
{
    "text": [
        """Below is an instruction that describes a task, paired with an input that provides further context. 
        Write a response that appropriately completes the request. 
        Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

        ### Instruction:
        You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning. 
        Please answer the following medical question. 

        ### Question:
        What is the cause of headache?

        ### Response:
        <think>
        The causes of headaches are numerous, including tension, dehydration, or sinus issues.
        </think>
        A headache can be caused by stress, lack of sleep, or a sinus infection. <|endoftext|>
        """,
        """Below is an instruction that describes a task, paired with an input that provides further context. 
        Write a response that appropriately completes the request. 
        Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

        ### Instruction:
        You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning. 
        Please answer the following medical question. 

        ### Question:
        How do you treat a cold?

        ### Response:
        <think>
        Treating a cold typically involves rest, fluids, and over-the-counter medications for symptoms.
        </think>
        For a cold, hydration and rest are key. Medications like ibuprofen can help with symptoms. <|endoftext|>
        """
    ]
}

3.3 訓(xùn)練數(shù)據(jù)

  1. setup_wandb: 配置并登錄到 wandb 進(jìn)行實(shí)驗(yàn)跟蹤和日志記錄。
  2. set_paths: 設(shè)置根目錄、模型路徑、數(shù)據(jù)集路徑和保存微調(diào)模型的路徑。
  3. load_model_and_tokenizer: 加載預(yù)訓(xùn)練模型和分詞器,獲取結(jié)束符。
  4. formatting_prompts_func: 格式化數(shù)據(jù)集中的問(wèn)題和回答,以便訓(xùn)練。
  5. setup_lora: 配置并應(yīng)用LoRA(低秩適配器)到模型。
  6. load_dataset_func: 加載數(shù)據(jù)集并進(jìn)行切分,返回訓(xùn)練集和評(píng)估集。
  7. setup_training_args: 設(shè)置訓(xùn)練參數(shù),包括學(xué)習(xí)率、批處理大小、訓(xùn)練周期等。
  8. train_model: 使用 SFTTrainer 進(jìn)行模型訓(xùn)練。
  9. save_model: 保存訓(xùn)練好的模型到指定路徑。
import os
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from datasets import load_dataset
from peft import get_peft_model, LoraConfig
from trl import SFTTrainer  # 使用 SFTTrainer
import wandb
from config import setting

# 設(shè)置環(huán)境變量,禁用tokenizer的并行化
os.environ["TOKENIZERS_PARALLELISM"] = "false"


# 登錄wandb
defsetup_wandb():
    """
    登錄到wandb以便記錄訓(xùn)練過(guò)程中的日志和指標(biāo)。
    """
    wandb.login()


# 設(shè)置路徑
defset_paths():
    """
    設(shè)置項(xiàng)目根目錄、模型路徑、數(shù)據(jù)集路徑和最終模型保存路徑。

    Returns:
        model_dir (str): 模型文件路徑
        dataset_path (str): 數(shù)據(jù)集路徑
        final_model_dir (str): 微調(diào)后模型的保存路徑
    """
    root_dir = setting.root_dir  # 項(xiàng)目根路徑
    model_dir = os.path.join(root_dir, 'models', 'DeepSeek-R1-Distill-Qwen-1.5B')  # 模型文件路徑
    dataset_path = os.path.join(root_dir, 'data', 'medical-o1-reasoning-SFT')  # 數(shù)據(jù)集路徑
    final_model_dir = os.path.join(root_dir, 'models', 'final_model')  # 高效微調(diào)后模型保存路徑
    print(f'設(shè)置模型路徑:{model_dir} | 數(shù)據(jù)集位置:{dataset_path}')
    return model_dir, dataset_path, final_model_dir


# 加載模型和分詞器
defload_model_and_tokenizer(model_dir):
    """
    加載預(yù)訓(xùn)練模型和對(duì)應(yīng)的分詞器,并獲取結(jié)束符(EOS_TOKEN)。

    Args:
        model_dir (str): 模型的文件路徑

    Returns:
        model (AutoModelForCausalLM): 加載的模型
        tokenizer (AutoTokenizer): 加載的分詞器
        EOS_TOKEN (str): 模型的結(jié)束符(如果沒(méi)有,使用默認(rèn)值)
    """
    print("加載分詞器:Loading model and tokenizer...")
    model = AutoModelForCausalLM.from_pretrained(model_dir)
    tokenizer = AutoTokenizer.from_pretrained(model_dir)

    EOS_TOKEN = tokenizer.eos_token
    if EOS_TOKEN isNone:
        EOS_TOKEN = "<|endoftext|>"

    print(f'結(jié)束符:{EOS_TOKEN}')
    return model, tokenizer, EOS_TOKEN


# 格式化訓(xùn)練數(shù)據(jù)
defformatting_prompts_func(examples, EOS_TOKEN):
    """
    格式化數(shù)據(jù)集中的每個(gè)示例,使其符合訓(xùn)練的要求。

    Args:
        examples (dict): 數(shù)據(jù)集中的輸入示例
        EOS_TOKEN (str): 結(jié)束符

    Returns:
        dict: 格式化后的文本數(shù)據(jù)
    """
    train_prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context. 
    Write a response that appropriately completes the request. 
    Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.

    ### Instruction:
    You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning. 
    Please answer the following medical question. 

    ### Question:
    {}

    ### Response:
    <think>
    {}
    </think>
    {}"""

    inputs = examples["Question"]
    cots = examples["Complex_CoT"]
    outputs = examples["Response"]
    texts = []
    forinput, cot, output inzip(inputs, cots, outputs):
        text = train_prompt_style.format(input, cot, output) + EOS_TOKEN
        texts.append(text)
    return {"text": texts}


# 設(shè)置LoRA配置
defsetup_lora(model):
    """
    設(shè)置LoRA(低秩適配器)配置,并將其應(yīng)用到模型。

    Args:
        model (AutoModelForCausalLM): 加載的模型

    Returns:
        model (AutoModelForCausalLM): 應(yīng)用LoRA后的模型
    """
    print("設(shè)置LoRA: Setting up LoRA configuration...")
    lora_config = LoraConfig(
        r=8,  # adapter的秩
        lora_alpha=32,  # 縮放因子
        lora_dropout=0.1,  # LoRA層的dropout
        bias="none",  # LoRA的偏置項(xiàng)
    )
    return get_peft_model(model, lora_config)


# 加載數(shù)據(jù)集
defload_dataset_func(dataset_path, train_size=100):
    """
    從指定路徑加載數(shù)據(jù)集,訓(xùn)練集大小為 train_size,評(píng)估集為訓(xùn)練集的10%,但至少為1。
    """
    print(f"從 {dataset_path} 加載數(shù)據(jù)集...")
    # 加載數(shù)據(jù)集
    dataset = load_dataset(dataset_path, "en", split="train", trust_remote_code=True)

    # 計(jì)算評(píng)估集大小
    eval_size = max(1, int(train_size * 0.1))  # 評(píng)估集大小是訓(xùn)練集的10%,但至少為1

    # 切分?jǐn)?shù)據(jù)集
    train_dataset = dataset.select(range(train_size))  # 使用前 train_size 條作為訓(xùn)練集
    eval_dataset = dataset.select(range(train_size, train_size + eval_size))  # 剩余部分作為評(píng)估集

    print(f"訓(xùn)練集大小: {len(train_dataset)}, 評(píng)估集大小: {len(eval_dataset)}")
    return train_dataset, eval_dataset


# 配置訓(xùn)練參數(shù)
defsetup_training_args(final_model_dir, enable_evaluation=True):
    """
    設(shè)置訓(xùn)練參數(shù),包括輸出目錄、學(xué)習(xí)率、批處理大小等,并根據(jù)參數(shù)控制是否啟用評(píng)估。

    Args:
        final_model_dir (str): 微調(diào)后模型保存的路徑
        enable_evaluation (bool): 是否啟用評(píng)估。默認(rèn)為T(mén)rue,啟用評(píng)估;為False時(shí)禁用評(píng)估。

    Returns:
        training_args (TrainingArguments): 訓(xùn)練參數(shù)
    """
    # 根據(jù)是否啟用評(píng)估設(shè)置 evaluation_strategy
    evaluation_strategy = "epoch"if enable_evaluation else"no"

    training_args = TrainingArguments(
        output_dir=final_model_dir,
        evaluation_strategy=evaluation_strategy,  # 控制評(píng)估策略
        learning_rate=5e-5,
        per_device_train_batch_size=2,  # 適當(dāng)減少批處理大小(根據(jù)M3 Pro的內(nèi)存限制)
        gradient_accumulation_steps=4,  # 使用梯度累積,模擬更大的批量
        num_train_epochs=3,  # 訓(xùn)練3個(gè)周期
        report_to="wandb",  # 使用wandb進(jìn)行訓(xùn)練日志記錄
        weight_decay=0.01,
        logging_dir=os.path.join(setting.root_dir, 'logs'),
        logging_steps=50,  # 減少日志記錄頻率
        save_steps=500,  # 增加模型保存的步數(shù)頻率,減少頻繁保存
        save_total_limit=2,  # 保存最多2個(gè)模型
        dataloader_num_workers=4,  # 設(shè)置數(shù)據(jù)加載器的并行數(shù)(根據(jù)需要調(diào)整)
    )
    return training_args



# 訓(xùn)練模型
deftrain_model(model, training_args, dataset, eval_dataset, tokenizer, enable_evaluation=True):
    """
    使用SFTTrainer進(jìn)行模型訓(xùn)練。

    Args:
        model (AutoModelForCausalLM): 需要訓(xùn)練的模型
        training_args (TrainingArguments): 訓(xùn)練參數(shù)
        dataset (Dataset): 用于訓(xùn)練的數(shù)據(jù)集
        eval_dataset (Dataset): 用于評(píng)估的數(shù)據(jù)集
        tokenizer (AutoTokenizer): 分詞器
        enable_evaluation (bool): 是否進(jìn)行評(píng)估

    Returns:
        trainer (SFTTrainer): 訓(xùn)練器實(shí)例
    """
    # 如果啟用了評(píng)估,傳遞評(píng)估集
    trainer = SFTTrainer(
        model=model,
        args=training_args,
        train_dataset=dataset,
        eval_dataset=eval_dataset if enable_evaluation elseNone,  # 根據(jù)參數(shù)決定是否傳遞評(píng)估集
        tokenizer=tokenizer,
        data_collator=None,  # 可以選擇合適的data collator
    )
    trainer.train()
    return trainer


# 保存模型
defsave_model(trainer, final_model_dir):
    """
    保存訓(xùn)練后的模型到指定目錄。

    Args:
        trainer (SFTTrainer): 訓(xùn)練器實(shí)例
        final_model_dir (str): 模型保存路徑
    """
    print("Saving model...")
    trainer.save_model(final_model_dir)



defmerge_models(models, weights, device="cpu"):
    """
    合并多個(gè)模型的權(quán)重(加權(quán)平均)。

    Args:
        models (list): 模型列表
        weights (list): 權(quán)重列表,權(quán)重?cái)?shù)量與模型數(shù)量一致
        device (str): 設(shè)備,可以是 "cuda" 或 "cpu"

    Returns:
        merged_model (nn.Module): 合并后的模型
    """
    # 確保模型數(shù)量與權(quán)重?cái)?shù)量一致
    assertlen(models) == len(weights), "模型數(shù)量與權(quán)重?cái)?shù)量不一致"

    # 將所有模型加載到相同的設(shè)備
    for i inrange(len(models)):
        models[i] = models[i].to(device)

    # 獲取第一個(gè)模型的狀態(tài)字典
    merged_state_dict = models[0].state_dict()

    # 對(duì)每一層的權(quán)重進(jìn)行加權(quán)平均
    for key in merged_state_dict.keys():
        merged_state_dict[key] = torch.zeros_like(merged_state_dict[key])
        for model, weight inzip(models, weights):
            merged_state_dict[key] += model.state_dict()[key] * weight

    # 創(chuàng)建一個(gè)新的模型并加載合并后的權(quán)重
    merged_model = models[0].__class__.from_pretrained(models[0].config)
    merged_model.load_state_dict(merged_state_dict)
    return merged_model


# 主函數(shù)
defmain():
    """
    主函數(shù),執(zhí)行整個(gè)訓(xùn)練流程:設(shè)置路徑、加載模型、訓(xùn)練并保存模型。

    參數(shù)設(shè)置:
            enable_evaluation = False  # 設(shè)置為False以禁用評(píng)估 如果性能慢可以設(shè)置 False

    加載數(shù)據(jù)集:
        train_size=10 設(shè)置數(shù)據(jù)集大小,評(píng)估集是數(shù)據(jù)集百分之10(如果小于1 則等于1 )
        train_dataset, eval_dataset = load_dataset_func(dataset_path, train_size=10)


    """
    setup_wandb()  # 登錄wandb
    model_dir, dataset_path, final_model_dir = set_paths()  # 設(shè)置路徑

    model, tokenizer, EOS_TOKEN = load_model_and_tokenizer(model_dir)  # 加載模型和分詞器

    train_dataset, eval_dataset = load_dataset_func(dataset_path, train_size=5)  # 加載數(shù)據(jù)集
    train_dataset = train_dataset.map(lambda examples: formatting_prompts_func(examples, EOS_TOKEN), batched=True)  # 格式化數(shù)據(jù)集
    eval_dataset = eval_dataset.map(lambda examples: formatting_prompts_func(examples, EOS_TOKEN), batched=True)  # 格式化評(píng)估集
    print(train_dataset["text"][0])  # 打印格式化后的數(shù)據(jù)

    model = setup_lora(model)  # 配置LoRA
    # 設(shè)置是否開(kāi)啟評(píng)估
    enable_evaluation = True# 設(shè)置為False以禁用評(píng)估
    training_args = setup_training_args(final_model_dir,enable_evaluation)  # 配置訓(xùn)練參數(shù)
    trainer = train_model(model, training_args, train_dataset, eval_dataset, tokenizer, enable_evaluation)  # 開(kāi)始訓(xùn)練

    save_model(trainer, final_model_dir)  # 保存模型
    wandb.finish()  # 完成wandb記錄




# 執(zhí)行主函數(shù)
if __name__ == "__main__":
    main()

3.4 訓(xùn)練模型并保存

"""
保存在本地 models/final_model 路徑下

"""

defsave_model(trainer, final_model_dir):
    """
    保存訓(xùn)練后的模型到指定目錄。

    Args:
        trainer (SFTTrainer): 訓(xùn)練器實(shí)例
        final_model_dir (str): 模型保存路徑
    """
    print("Saving model...")
    trainer.save_model(final_model_dir)

3.5 合并模型文件

#01 執(zhí)行即可
new_model_local = "DeepSeek-R1-Medical-COT-Tiny"
model.save_pretrained(new_model_local) 
tokenizer.save_pretrained(new_model_local)
model.save_pretrained_merged(new_model_local, tokenizer, save_method = "merged_16bit",)

3.6 評(píng)估和監(jiān)控訓(xùn)練過(guò)程

評(píng)估(eval/)相關(guān)信息:

  • eval/runtime 18.3908: 評(píng)估過(guò)程總共耗時(shí)18.39秒。
  • eval/samples_per_second 0.054: 每秒處理的樣本數(shù)為0.054,表示評(píng)估的速度較慢。
  • eval/steps_per_second 0.054: 每秒進(jìn)行評(píng)估步數(shù)為0.054,說(shuō)明每個(gè)評(píng)估步驟的時(shí)間消耗較大。

訓(xùn)練(train/)相關(guān)信息:

  • train/epoch 0: 當(dāng)前訓(xùn)練輪次是第0輪。
  • train/global_step 0: 當(dāng)前全局步驟為0,表示尚未進(jìn)行任何訓(xùn)練步驟。
  • train_loss 14435.36663: 當(dāng)前訓(xùn)練的損失為14435.37,表明模型的表現(xiàn)尚不理想,通常需要更多的訓(xùn)練來(lái)降低損失。
  • train/runtime 251.7582: 訓(xùn)練總時(shí)間為251.76秒。
  • train/samples_per_second 0.06: 每秒處理的訓(xùn)練樣本數(shù)為0.06,訓(xùn)練的速度較慢。
  • train/steps_per_second 0.012: 每秒進(jìn)行的訓(xùn)練步數(shù)為0.012,表示每個(gè)訓(xùn)練步驟消耗的時(shí)間較長(zhǎng)。
#02 詳細(xì)日志
wandb: ?? View project at https://wandb.ai/z15119911990-beijing/huggingface
wandb: ?? View run at https://wandb.ai/z15119911990-beijing/huggingface/runs/mgrko2jv
  0%|          | 0/3 [00:00<?, ?it/s]
{'eval_runtime': 14.8693, 'eval_samples_per_second': 0.067, 'eval_steps_per_second': 0.067, 'epoch': 0}
                                     
  0%|          | 0/3 [00:30<?, ?it/s]
100%|██████████| 1/1 [00:00<00:00, 1461.94it/s]
                                               
                                     
{'eval_runtime': 21.2073, 'eval_samples_per_second': 0.047, 'eval_steps_per_second': 0.047, 'epoch': 0}
  0%|          | 0/3 [02:11<?, ?it/s]
100%|██████████| 1/1 [00:00<00:00, 33.69it/s]
                                             
                                     
  0%|          | 0/3 [04:02<?, ?it/s]
100%|██████████| 1/1 [00:00<00:00, 334.66it/s]
                                              {'eval_runtime': 18.3908, 'eval_samples_per_second': 0.054, 'eval_steps_per_second': 0.054, 'epoch': 0}
{'train_runtime': 251.7582, 'train_samples_per_second': 0.06, 'train_steps_per_second': 0.012, 'train_loss': 14435.3666305542, 'epoch': 0}
  0%|          | 0/3 [04:10<?, ?it/s]
wandb:                                                                                
wandb: 
wandb: Run history:
wandb:            eval/runtime ▁█▅
wandb: eval/samples_per_second █▁▃
wandb:   eval/steps_per_second █▁▃
wandb:             train/epoch ▁▁▁▁
wandb:       train/global_step ▁▁▁▁
wandb: 
wandb: Run summary:
wandb:             eval/runtime 18.3908
wandb:  eval/samples_per_second 0.054
wandb:    eval/steps_per_second 0.054
wandb:               total_flos 43804457687040.0
wandb:              train/epoch 0
wandb:        train/global_step 0
wandb:               train_loss 14435.36663
wandb:            train_runtime 251.7582
wandb: train_samples_per_second 0.06
wandb:   train_steps_per_second 0.012
wandb: 
wandb: ?? View run /Users/ningcaichen/Documents/02-python相關(guān)文檔/01-AI系列/LoRA-DeepSeek-R1/models/final_model at: https://wandb.ai/z15119911990-beijing/huggingface/runs/mgrko2jv
wandb: ?? View project at: https://wandb.ai/z15119911990-beijing/huggingface
wandb: Synced 5 W&B file(s), 0 media file(s), 0 artifact file(s) and 0 other file(s)
wandb: Find logs at: ./wandb/run-20250212_133457-mgrko2jv/logs


責(zé)任編輯:武曉燕 來(lái)源: 海邊的拾遺者
相關(guān)推薦

2023-01-09 08:00:00

遷移學(xué)習(xí)機(jī)器學(xué)習(xí)數(shù)據(jù)集

2024-01-24 13:37:36

大型語(yǔ)言模型人工智能

2025-02-25 12:08:26

2025-02-07 14:04:44

2024-12-30 00:01:00

多模態(tài)大模型Python

2024-04-19 12:50:58

人工智能OpenAI

2025-03-11 08:37:42

2025-03-31 08:28:24

大型語(yǔ)言模型LLMDeepSeek

2025-02-08 14:03:25

2025-02-24 12:22:13

DeepSeek開(kāi)源模型

2025-05-16 08:58:09

2024-06-06 08:25:30

2025-02-14 10:00:00

DeepSeekAI大模型

2024-08-28 08:43:58

2025-02-13 08:51:23

DeepSeek大模型

2023-06-16 13:37:00

AI學(xué)習(xí)

2025-03-04 17:27:05

2025-02-25 11:35:36

2023-09-01 21:12:13

GPT3.5模型微調(diào)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)