用Unsloth微調(diào)一個老中醫(yī)大模型
本文介紹了如何使用Unsloth框架微調(diào)大語言模型,以《傷寒論》數(shù)據(jù)集為例訓(xùn)練一個中醫(yī)專家模型。Unsloth顯著降低了微調(diào)的資源需求。文章涵蓋了從環(huán)境配置、模型選擇、數(shù)據(jù)準(zhǔn)備到訓(xùn)練部署的完整流程,為垂直領(lǐng)域模型微調(diào)提供了實用參考。
1. 關(guān)于Unsloth
2. Unsloth 的核心優(yōu)勢
3. 使用要求
4. 安裝 Unsloth
5. 選擇模型
6. 數(shù)據(jù)集準(zhǔn)備
7. 開始微調(diào)
7.1 引入依賴
7.2 加載模型
7.3 加載數(shù)據(jù)集
7.4 定義 LoRA
7.5 使用 `SFTTrainer` 進行訓(xùn)練
7.6 模型保存
7.7 訓(xùn)練過程
8. 測試微調(diào)的模型
在實際應(yīng)用中,我們常常面臨特定場景下的問題需求。此時,通過指令微調(diào)可以讓模型更好地適應(yīng)這些具體任務(wù),從而提升模型的實用性和表現(xiàn)。
比如:在醫(yī)療健康領(lǐng)域,醫(yī)生希望讓大模型更好地理解中醫(yī)診斷和治療的知識體系,從而能夠輔助分析病情、推薦中藥方劑,甚至自動生成病歷摘要。又如,在法律行業(yè),律師團隊希望通過微調(diào),讓大模型能夠更準(zhǔn)確地解讀中國法律條文、判例和合同文本,輔助法律檢索和文書生成。此外,在教育領(lǐng)域,教師可以通過指令微調(diào),讓模型更貼合本地教材內(nèi)容,自動批改作業(yè)、生成個性化學(xué)習(xí)建議。這些場景都需要針對特定任務(wù)和數(shù)據(jù)對大模型進行定制化微調(diào),以提升其在實際應(yīng)用中的表現(xiàn)和價值。
正好最近身體不適,并且得到一本醫(yī)療秘籍《傷寒論》,用 ??Unsloth?? 來微調(diào)一個垂直領(lǐng)域的模型出來。
完整代碼,在公眾號「AI取經(jīng)路」發(fā)消息「微調(diào)」獲取
1. 關(guān)于Unsloth
大型語言模型(LLM)的微調(diào)有很大的資源挑戰(zhàn),如高昂的內(nèi)存需求和漫長的訓(xùn)練時間。
傳統(tǒng)的微調(diào)方法,可能需要數(shù)十小時才能完成一項任務(wù),并且常常導(dǎo)致內(nèi)存不足問題 。這種特性限制了個人開發(fā)者和小型團隊對 LLM 進行定制化和優(yōu)化的能力。
Unsloth 正是為了解決這些痛點而誕生的。
它是一個專門為加速 LLM 微調(diào)并顯著降低內(nèi)存消耗而設(shè)計的 Python 框架 。
Unsloth 實現(xiàn)了顯著的性能提升,同時保持了與 Hugging Face 生態(tài)系統(tǒng)的完全兼容性 。這使得用戶即使在免費的 Colab GPU 或配備 GPU 的筆記本電腦等有限硬件上,也能夠高效地進行 LLM 微調(diào) 。
2. Unsloth 的核心優(yōu)勢
速度提升
在Alpaca 數(shù)據(jù)集上進行了測試,使用的 batch 大小為 2,gradient accumulation steps 為 4,rank 為 32,并在所有線性層(q、k、v、o、gate、up、down)上應(yīng)用了 QLoRA
Model  | VRAM  | Unsloth speed  | VRAM reduction  | Longer context  | Hugging Face + FA2  | 
Llama 3.3 (70B)  | 80GB  | 2x  | >75%  | 13x longer  | 1x  | 
Llama 3.1 (8B)  | 80GB  | 2x  | >70%  | 12x longer  | 1x  | 
測試結(jié)果顯示,兩種模型在顯存使用上均為80GB,速度均提升了2倍。Llama 3.3的顯存減少了超過75%,能夠處理的上下文長度提升了13倍;而Llama 3.1的顯存減少了超過70%,上下文長度提升了12倍。
API 簡化
Unsloth 提供了一個簡潔的 API,顯著降低了 LLM 微調(diào)的復(fù)雜性 。它將模型加載、量化、訓(xùn)練、評估、保存、導(dǎo)出以及與 Ollama、llama.cpp 和 vLLM 等推理引擎的集成等所有工作流程進行了簡化 。
Hugging Face 生態(tài)系統(tǒng)兼容性
Unsloth 是在 Hugging Face Transformers 庫之上構(gòu)建的,這使其能夠充分利用 Hugging Face 強大的生態(tài)系統(tǒng),同時添加自己的增強功能來簡化微調(diào)過程 。
它與 Hugging Face Hub、Transformers、PEFT 和 TRL 等組件完全兼容 。這意味著用戶可以無縫地訪問 Hugging Face 提供的豐富模型和數(shù)據(jù)集資源,并利用 Unsloth 的優(yōu)化進行訓(xùn)練。
硬件兼容性與可訪問性
Unsloth 支持非常多的 NVIDIA GPU,從 2018 年及以后發(fā)布的型號,包括 V100、T4、Titan V、RTX 20、30、40 系列、A100 和 H100 等,最低 CUDA 能力要求為 7.0。即使是 GTX 1070 和 1080 也能工作,盡管速度較慢 。
Unsloth 可以在 Linux 和 Windows 操作系統(tǒng)上運行 。
廣泛的模型支持
Unsloth 支持所有 Transformer 風(fēng)格的模型,包括 Llama、DeepSeek、TTS、Qwen、Mistral、Gemma 等主流 LLM。它還支持多模態(tài)模型、文本到語音 (TTS)、語音到文本 (STT) 模型、BERT 模型以及擴散模型。
動態(tài)量化
Unsloth 引入了動態(tài) 4 位量化 (Dynamic 4-bit Quantization) 技術(shù),這是一種智能的量化策略,通過動態(tài)選擇不對某些參數(shù)進行量化,從而在僅增加不到 10% VRAM 的情況下顯著提高準(zhǔn)確性 。
社區(qū)的活躍
從GitHub上可以看出,他的受歡迎程度非常高,目前已經(jīng)43k顆星
3. 使用要求
支持 Linux 和 Windows。
支持 2018 年及以后的 NVIDIA 顯卡,包括 Blackwell RTX 50 系列。最低要求 CUDA 計算能力為 7.0(如 V100、T4、Titan V、RTX 20、30、40 系列,以及 A100、H100、L40 等)。GTX 1070、1080 雖然可以使用,但運行速度較慢。
相關(guān)閱讀:???一文說清楚CUDA環(huán)境??
GPU內(nèi)存要求:
Model parameters  | QLoRA (4-bit) VRAM  | LoRA (16-bit) VRAM  | 
3B  | 3.5 GB  | 8 GB  | 
7B  | 5 GB  | 19 GB  | 
8B  | 6 GB  | 22 GB  | 
9B  | 6.5 GB  | 24 GB  | 
11B  | 7.5 GB  | 29 GB  | 
14B  | 8.5 GB  | 33 GB  | 
27B  | 22GB  | 64GB  | 
32B  | 26 GB  | 76 GB  | 
40B  | 30GB  | 96GB  | 
70B  | 41 GB  | 164 GB  | 
81B  | 48GB  | 192GB  | 
90B  | 53GB  | 212GB  | 
405B  | 237 GB  | 950 GB  | 
4. 安裝 Unsloth
# 初始化一個名為 demo-unsloth 的項目,并指定 Python 版本為 3.11.9
uv init demo-unsloth -p 3.11.9
# 進入項目目錄
cd demo-unsloth
# 創(chuàng)建虛擬環(huán)境
uv venv
# 激活虛擬環(huán)境(Windows 下)
.venv\Scripts\activate
# 安裝 triton-windows,要求版本3.3.1.post19
uv pip install triton-windows==3.3.1.post19
# 安裝支持 CUDA 12.6 的 PyTorch 及其相關(guān)庫
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126安裝unsloth
uv pip install unsloth5. 選擇模型
Unsloth 支持非常多的預(yù)訓(xùn)練模型,包括 Llama、DeepSeek、TTS、Qwen、Mistral 和 Gemma 系列 LLM 3。
在選擇模型時,需要注意模型名稱的后綴。以 ??unsloth-bnb-4bit??? 結(jié)尾的模型表示它們是 Unsloth 動態(tài) 4 位量化模型,與標(biāo)準(zhǔn) ??bnb-4bit?? 模型相比,這些模型在略微增加 VRAM 使用的情況下提供了更高的精度。
??https://docs.unsloth.ai/get-started/all-our-models??
我的顯卡是RTX 2050顯卡,4GB顯存,我選一個比較小的版本 unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit
下載模型:
huggingface-cli download --resume-download unsloth/Qwen2.5-1.5B-Instruct-bnb-4bit --local-dir ./ckpts/qwen2.5-1.5b-instruct-bnb-4bit6. 數(shù)據(jù)集準(zhǔn)備
數(shù)據(jù)集的質(zhì)量和格式直接決定了模型微調(diào)的效果。
一個高質(zhì)量的數(shù)據(jù)集不僅需要覆蓋目標(biāo)任務(wù)的核心內(nèi)容,還應(yīng)保證問答對的準(zhǔn)確性、完整性和多樣性。
此外,數(shù)據(jù)集的規(guī)模也會影響模型的泛化能力,數(shù)據(jù)量越大、覆蓋面越廣,模型在實際應(yīng)用中的表現(xiàn)通常會更好。
因此,在微調(diào)前應(yīng)充分清洗、標(biāo)注和檢查數(shù)據(jù),確保其能夠有效支撐下游任務(wù)的訓(xùn)練需求。
因為要要訓(xùn)練一個老中醫(yī),所以找了一本《傷寒論》,通過工具把他拆成問答對,格式如下
[
  {
    "Question": "傷寒一日,巨陽受之會出現(xiàn)什么癥狀?",
    "Response": "傷寒一日,巨陽受之會出現(xiàn)頭項痛、腰脊強的癥狀。因為巨陽者,諸陽之屬也,其脈連于風(fēng)府,為諸陽主氣,所以先受邪。 "
  },
  {
    "Question": "三陰受病,厥陰受之會出現(xiàn)什么癥狀",
    "Response": "三陰受病,若厥陰受之,厥陰脈循陰器而絡(luò)于肝,會出現(xiàn)煩滿而囊縮的癥狀。 若傷寒循常無變,十二日厥陰病衰,會出現(xiàn)囊縱、少腹微下的情況。 "
  },
]7. 開始微調(diào)
7.1 引入依賴
# 導(dǎo)入必要的庫
from unsloth import FastLanguageModel, is_bfloat16_supported
from transformers import TrainingArguments, EarlyStoppingCallback
from trl import SFTTrainer
from datasets import load_dataset
# 模型配置參數(shù)
max_seq_length = 2048  # 模型處理文本的最大序列長度,支持長文本輸入7.2 加載模型
# 加載預(yù)訓(xùn)練模型和分詞器
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="ckpts/qwen2.5-1.5b-instruct-bnb-4bit",
    max_seq_length=max_seq_length,
    dtype=None,  # 自動檢測最佳數(shù)據(jù)類型(bfloat16或float16)
    load_in_4bit=True,  # 使用4bit量化加載模型,大幅減少顯存占用
)7.3 加載數(shù)據(jù)集
大型語言模型需要以特定的“提示風(fēng)格”或“聊天模板”來接收輸入,以便它們能夠正確理解任務(wù)、指令、輸入和預(yù)期響應(yīng)之間的關(guān)系。
例如,一個常用的提示風(fēng)格是:
“請先閱讀下方的任務(wù)指令,再結(jié)合提供的上下文信息,生成恰當(dāng)?shù)幕貜?fù)。### 指令:{} ### 上下文:{} ### 回復(fù):{}”有效的微調(diào)需要仔細關(guān)注輸入格式,因為它直接影響模型學(xué)習(xí)的內(nèi)容和響應(yīng)方式
下面代碼中加載我們的《傷寒論》數(shù)據(jù)集( ??data/datasets-2025-08.json???),并使用 ??formatting_data??? 函數(shù)將其轉(zhuǎn)換為 Unsloth 所需的格式,此函數(shù)會結(jié)合輸入和輸出,按照 ??prompt_style??? 進行格式化,并添加 ??EOS_TOKEN???(End-of-Sentence Token),??EOS_TOKEN?? 對于避免模型生成重復(fù)內(nèi)容至關(guān)重要。
# 定義訓(xùn)練數(shù)據(jù)格式化模板
# 使用中醫(yī)專家角色設(shè)定,專門針對《傷寒論》問答任務(wù)
train_prompt_style = """你是一位精通中醫(yī)理論的專家,特別擅長《傷寒論》的理論和實踐應(yīng)用。
請根據(jù)《傷寒論》的經(jīng)典理論,準(zhǔn)確回答以下問題。
### 問題:
{}
### 回答:
{}
"""
# 加載訓(xùn)練數(shù)據(jù)集
# 從JSON文件加載傷寒論問答數(shù)據(jù)集,包含問題和回答對
dataset = load_dataset("json", data_files="data/datasets-2025-08.json", split="train")  
def formatting_data(examples):
    """格式化數(shù)據(jù)集函數(shù),將問答對轉(zhuǎn)換為訓(xùn)練格式
    
    將原始的問題和回答對格式化為模型訓(xùn)練所需的文本格式,
    添加角色設(shè)定和結(jié)構(gòu)化模板。
    Args:
        examples: 包含Question、Response字段的數(shù)據(jù)樣本字典
    Returns:
        dict: 包含格式化后文本的字典,鍵為"text"
    """
    questions = examples["Question"]
    responses = examples["Response"]
    texts = []
    for q, r in zip(questions, responses):
        # 使用模板格式化每個問答對,并添加結(jié)束標(biāo)記
        text = train_prompt_style.format(q, r) + tokenizer.eos_token
        texts.append(text)
    # print(f"數(shù)據(jù)集: {texts}")
    return {"text": texts}
# 應(yīng)用數(shù)據(jù)格式化函數(shù)
dataset = dataset.map(formatting_data, batched=True, num_proc=1)
# 數(shù)據(jù)集分割:80%用于訓(xùn)練,20%用于驗證
# 使用固定隨機種子確保結(jié)果可復(fù)現(xiàn)
train_test_split = dataset.train_test_split(test_size=0.2, seed=3407)
train_dataset = train_test_split['train']
eval_dataset = train_test_split['test']
print(f"數(shù)據(jù)集加載完成 - 訓(xùn)練集: {len(train_dataset)} 條, 驗證集: {len(eval_dataset)} 條")7.4 定義 LoRA
# 添加LoRA(Low-Rank Adaptation)權(quán)重配置
# LoRA是一種高效的微調(diào)方法,只訓(xùn)練少量參數(shù)即可適應(yīng)新任務(wù)
model = FastLanguageModel.get_peft_model(
    model,
    r=32,  # LoRA矩陣的秩,值越大表達能力越強,但參數(shù)量也越多
    target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj", ],
    lora_alpha=64,  # LoRA縮放參數(shù)
    lora_dropout=0.1,  # LoRA dropout率,防止過擬合,值越小正則化越弱
    bias="none",  # 偏置項處理方式,"none"表示不訓(xùn)練偏置,節(jié)省參數(shù)
    use_gradient_checkpointing="unsloth",  # 使用Unsloth優(yōu)化的梯度檢查點,支持超長序列
    random_state=3407,  # 隨機種子,確保結(jié)果可復(fù)現(xiàn)
    use_rslora=False,  # 是否使用Rank Stabilized LoRA,當(dāng)前使用標(biāo)準(zhǔn)LoRA
    loftq_cnotallow=None,  # LoftQ配置,用于更精確的量化
)?7.5 使用 ???SFTTrainer?? 進行訓(xùn)練?
# 創(chuàng)建SFT(Supervised Fine-Tuning)訓(xùn)練器
# 使用監(jiān)督學(xué)習(xí)方式微調(diào)模型,適用于問答任務(wù)
trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=train_dataset,  # 訓(xùn)練數(shù)據(jù)集
    eval_dataset=eval_dataset,  # 驗證數(shù)據(jù)集,用于評估模型性能
    dataset_text_field="text",  # 數(shù)據(jù)集中文本字段的名稱
    max_seq_length=max_seq_length,  # 最大序列長度
    dataset_num_proc=1,  # 數(shù)據(jù)處理進程數(shù),設(shè)為1避免緩存沖突
    packing=False,  # 是否使用序列打包,短序列時可設(shè)為True提升5倍訓(xùn)練速度
    callbacks=[
        EarlyStoppingCallback(early_stopping_patience=3, early_stopping_threshold=0.0005),  # 早停機制,防止過擬合
    ],
    args=TrainingArguments(
        # 批次大小配置
        per_device_train_batch_size=2,  # 每個GPU的訓(xùn)練批次大小
        per_device_eval_batch_size=2,  # 每個GPU的驗證批次大小
        
        # 梯度累積配置
        gradient_accumulation_steps=8,  # 梯度累積步數(shù),有效批次大小 = batch_size * gradient_accumulation_steps
        
        # 學(xué)習(xí)率配置
        warmup_ratio=0.15,  # 學(xué)習(xí)率預(yù)熱比例,前15%的步數(shù)用于預(yù)熱
        learning_rate=2e-5,  # 學(xué)習(xí)率,控制參數(shù)更新步長
        
        # 訓(xùn)練輪數(shù)和步數(shù)配置
        # max_steps = 200, # 最大訓(xùn)練步數(shù)(可選)
        num_train_epochs=5,  # 訓(xùn)練輪數(shù),給模型充分學(xué)習(xí)機會
        
        # 精度配置
        fp16=not is_bfloat16_supported(),  # 是否使用16位浮點精度訓(xùn)練
        bf16=is_bfloat16_supported(),  # 是否使用bfloat16精度訓(xùn)練(更穩(wěn)定)
        
        # 日志和監(jiān)控配置
        logging_steps=2,  # 每2步記錄一次日志
        eval_steps=10,  # 每10步進行一次驗證評估
        eval_strategy="steps",  # 按步數(shù)進行驗證
        
        # 模型保存配置
        save_steps=20,  # 每20步保存一次模型檢查點
        save_strategy="steps",  # 按步數(shù)保存模型
        save_total_limit=5,  # 最多保存5個檢查點,節(jié)省存儲空間
        
        # 最佳模型配置
        load_best_model_at_end=True,  # 訓(xùn)練結(jié)束時自動加載最佳模型
        metric_for_best_model="eval_loss",  # 使用驗證損失作為最佳模型指標(biāo)
        greater_is_better=False,  # 損失越小越好
        
        # 正則化配置
        weight_decay=0.001,  # 權(quán)重衰減,防止過擬合
        max_grad_norm=1.0,  # 梯度裁剪閾值,防止梯度爆炸
        
        # 學(xué)習(xí)率調(diào)度配置
        lr_scheduler_type="cosine",  # 使用余弦退火學(xué)習(xí)率調(diào)度器
        
        # 優(yōu)化器配置
        optim="adamw_8bit",  # 使用8位AdamW優(yōu)化器,節(jié)省顯存
        
        # 數(shù)據(jù)加載配置
        dataloader_num_workers=0,  # 數(shù)據(jù)加載器工作進程數(shù),設(shè)為0避免多進程沖突
        
        # 輸出配置
        output_dir="outputs",  # 模型輸出和檢查點保存目錄
        
        # 隨機種子
        seed=3407,  # 隨機種子,確保結(jié)果可復(fù)現(xiàn)
    ),
)
# 開始訓(xùn)練
train_stats = trainer.train()
print(f"訓(xùn)練完成,訓(xùn)練損失: \n {train_stats}")7.6 模型保存
Unsloth 提供了多種保存微調(diào)后模型的方法,每種方法都有其特定的用途:
???save_pretrained???
此方法僅保存 LoRA 適配器權(quán)重。這些文件通常很小,只包含模型修改部分,包括 ??adapter_config.json??? 和 ??adapter_model.safetensors?? 。這種方法適用于需要靈活切換不同 LoRA 適配器或節(jié)省存儲空間的情況。
???save_pretrained_gguf???
這是一種新的優(yōu)化格式(GGUF),支持更好的元數(shù)據(jù)處理。文件同樣較小且經(jīng)過量化,包括 ??model.gguf??? 和 ??tokenizer.json?? 。Unsloth 的動態(tài)量化在 GGUF 導(dǎo)出中通過智能的層特定量化策略,進一步增強了模型性能和效率。
# 保存微調(diào)后的模型權(quán)重
# 只保存LoRA權(quán)重,原始模型權(quán)重保持不變
model.save_pretrained("ckpts/qwen2.5-1.5b-instruct-bnb-4bit-lora")
# 保存分詞器(tokenizer),以便后續(xù)加載和推理時使用
tokenizer.save_pretrained("ckpts/qwen2.5-1.5b-instruct-bnb-4bit-lora")
#==================================================================================
# model.save_pretrained_gguf("ckpts/qwen2.5-1.5b-instruct-bnb-4bit-gguf", tokenizer, quantization_method="q4_k_m")7.7 訓(xùn)練過程
開始時顯示基礎(chǔ)信息:
==((====))==  Unsloth 2025.7.8: Fast Qwen3 patching. Transformers: 4.53.3.
   \\   /|    NVIDIA GeForce RTX 2050. Num GPUs = 1. Max memory: 4.0 GB. Platform: Windows.
O^O/ \_/ \    Torch: 2.7.1+cu126. CUDA: 8.6. CUDA Toolkit: 12.6. Triton: 3.3.1
\        /    Bfloat16 = TRUE. FA [Xformers = 0.0.31.post1. FA2 = False]
 "-____-"     Free license: http://github.com/unslothai/unsloth
# 批注:系統(tǒng)配置信息
# - 使用RTX 2050顯卡,4GB顯存
# - 支持bfloat16精度訓(xùn)練
# - 使用Xformers優(yōu)化注意力機制再給出微調(diào)的配置:
==((====))==  Unsloth - 2x faster free finetuning | Num GPUs used = 1
   \\   /|    Num examples = 353 | Num Epochs = 5 | Total steps = 115
O^O/ \_/ \    Batch size per device = 2 | Gradient accumulation steps = 8
\        /    Data Parallel GPUs = 1 | Total batch size (2 x 8 x 1) = 16
 "-____-"     Trainable parameters = 20,185,088 of 616,235,008 (3.28% trained)
# 批注:訓(xùn)練配置詳情
# - 總樣本數(shù):353個
# - 訓(xùn)練輪數(shù):5輪
# - 總步數(shù):115步
# - 有效批次大?。?6(2×8×1)
# - 可訓(xùn)練參數(shù):3.28%(20M/616M)后面是微調(diào)細節(jié):
{'loss': 2.1017, 'grad_norm': 3.180413007736206, 'learning_rate': 1.995283421166614e-05, 'epoch': 1.05}
{'loss': 2.2702, 'grad_norm': 2.8307971954345703, 'learning_rate': 1.9869167087338908e-05, 'epoch': 1.14}
{'loss': 2.0511, 'grad_norm': 3.1757583618164062, 'learning_rate': 1.9744105246469264e-05, 'epoch': 1.23}
{'loss': 2.1853, 'grad_norm': 2.5234906673431396, 'learning_rate': 1.957817324187987e-05, 'epoch': 1.32}
{'loss': 1.8145, 'grad_norm': 2.9424679279327393, 'learning_rate': 1.937206705006344e-05, 'epoch': 1.32}8. 測試微調(diào)的模型
模型測試代碼如下:
from unsloth import FastLanguageModel
from unsloth.chat_templates import get_chat_template
from transformers import TextStreamer
import torch
max_seq_length = 512
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="ckpts/qwen2.5-1.5b-instruct-bnb-4bit-lora",
    max_seq_length=max_seq_length,
    dtype=None,
    load_in_4bit=True,
)
# 啟用unsloth的2x更快推理優(yōu)化
print("啟用推理優(yōu)化...")
FastLanguageModel.for_inference(model)
print("模型加載完成")
# 定義訓(xùn)練數(shù)據(jù)格式化字符串模板
train_prompt_style = """你是一位精通中醫(yī)理論的專家,特別擅長《傷寒論》的理論和實踐應(yīng)用。
請根據(jù)《傷寒論》的經(jīng)典理論,準(zhǔn)確回答以下問題。
### 問題:
{}
"""
question = '什么是太陽病?'
formatted_prompt = train_prompt_style.format(question)
print(f"格式化后的提示文本:\n-------------------\n{formatted_prompt}\n-------------------")
print(type(tokenizer))   # <class 'transformers.models.qwen2.tokenization_qwen2_fast.Qwen2TokenizerFast'>
inputs = tokenizer([formatted_prompt], return_tensors='pt', max_length=max_seq_length).to("cuda")
print(f"inputs: \n-------------------\n{inputs}\n-------------------")
# 生成回答(流式輸出)
with torch.no_grad():
    outputs = model.generate(
        # 輸入序列的token ID
        inputs['input_ids'], 
        # 注意力掩碼,指示哪些位置是有效輸入
        attention_mask=inputs['attention_mask'], 
        # 生成文本的最大長度限制
        max_length=max_seq_length,
        # 啟用KV緩存,加速生成過程
        use_cache=True,
        # 溫度參數(shù),控制生成的隨機性
        # 值越低生成越確定,值越高生成越隨機
        temperature=0.8, 
        # 核采樣參數(shù),只從累積概率達到90%的詞中選擇
        # 避免選擇概率極低的詞,提高生成質(zhì)量
        top_p=0.9,
        # 啟用采樣模式,而不是貪婪解碼
        # 貪婪解碼總是選擇概率最高的詞,容易產(chǎn)生重復(fù)
        do_sample=True,
        # 設(shè)置填充標(biāo)記ID,用于處理變長序列
        pad_token_id=tokenizer.eos_token_id,
        # 設(shè)置結(jié)束標(biāo)記ID,告訴模型何時停止生成
        eos_token_id=tokenizer.eos_token_id,
        # 重復(fù)懲罰參數(shù),防止模型重復(fù)生成相同內(nèi)容
        # 1.1表示重復(fù)詞的生成概率降低10%
        repetition_penalty=1.1
    )
print(type(outputs))
print(outputs)
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
print("\n" + "=" * 80)
print(answer)
print("\n" + "=" * 80)
print("測試完成!")本文轉(zhuǎn)載自???AI取經(jīng)路??,作者:AI取經(jīng)路


















