欢迎光临
我们一直在努力

02_LoRA低秩适配原理与配置:Qwen模型的参数高效微调实战

二、LoRA低秩适配原理与配置:Qwen模型的参数高效微调实战

核心关键词: LoRA原理、低秩分解、LoRA配置参数、Qwen LoRA、PEFT、秩选择、target_modules、lora_alpha、缩放因子、QLoRA适配

标签: 大模型微调、LoRA、Qwen、参数高效微调、PEFT、低秩适配


上一篇文章把微调的整个流水线梳理了一遍,这一篇我们来深入LoRA本身。LoRA看起来简单——不就是给模型加两个小矩阵吗?但真正用起来才发现,配置参数选错了,轻则训不出效果,重则直接OOM。更麻烦的是,GitHub上各种教程给出的配置参数五花八门,有人说r=8够用了,有人说r=128才够,到底信谁?

这一篇我来把LoRA的核心原理讲透,再把我自己跑过几十个实验总结出的调参经验分享出来。不是玄学,每一条建议背后都有数据支撑。

一、LoRA核心数学原理

1.1 关键发现:内在秩假说

LoRA的理论基础是微软研究院在2021年论文《LoRA: Low-Rank Adaptation of Large Language Models》中提出的一个关键发现:大语言模型在适应新任务时,权重矩阵的更新矩阵具有较低的内在大秩(low intrinsic rank)。

这个发现的意义极其重大。传统观点认为,模型的全参数矩阵是"满秩"的,信息的分布非常分散。但实验发现,当模型学习新任务时,真正起作用的权重变化其实只分布在少数几个方向上——这意味着我们可以用低秩矩阵来捕捉这些变化。

用大白话说:与其训练整个大矩阵,不如只训练两个小矩阵的乘积,效果差不多。

1.2 数学推导:从全参数到低秩

传统的全参数微调是这样的:

原始权重: W₀ ∈ R^(d×d)
训练后权重: W' = W₀ + ΔW

可训练参数: d×d 个(假设d=4096,则有1600万+参数)

LoRA的创新在于用低秩分解来近似ΔW:

ΔW ≈ B × A

其中: A ∈ R^(r×d), B ∈ R^(d×r), r << d
可训练参数: 2 × r × d

示例: d=4096, r=16
– 全参数: 4096 × 4096 = 16,777,216 参数
– LoRA: 2 × 16 × 4096 = 131,072 参数
– 压缩比: 128倍!

前向传播的计算:

# 原始前向传播
h = W₀ @ x

# LoRA前向传播
h = W₀ @ x + (B @ A) @ x

# 实际实现中,只存储A和B
h = W₀ @ x + BA @ x

1.3 缩放因子的物理意义

LoRA引入了一个重要的超参数alpha(α),用于控制低秩更新的幅度:

# 带缩放的LoRA更新
h = W₀ @ x + (α/r) × BA @ x

# 为什么需要缩放?
# – 当r很大时,BA的初始值可能很大
# – α/r 使不同r值下,初始更新幅度保持一致

α与r的关系:

  • α = r:缩放因子为1,初始更新较保守
  • α = 2r:推荐,初始更新更明显
  • α < r:初始更新被压制,可能需要更多epoch

┌─────────────────────────────────────────────────────────────┐
│ LoRA更新幅度 = (α/r) × BA │
│ │
│ r=8, α=8 → 缩放=1.0 → 更新幅度适中 │
│ r=16, α=32 → 缩放=2.0 → 更新幅度翻倍(推荐) │
│ r=64, α=64 → 缩放=1.0 → 更新幅度适中 │
│ │
│ 核心思想:无论r选多少,α/r≈2是初始更新的舒适起点 │
└─────────────────────────────────────────────────────────────┘

1.4 为什么LoRA有效:秩与表达能力

这里有一个反直觉的发现:低秩矩阵的乘积BA ≠ 低秩矩阵BA。

# A ∈ R^(r×d), B ∈ R^(d×r)
# BA ∈ R^(d×d),虽然由低秩矩阵构成,但BA可能是满秩的!

# 举例:
# A = [1, 0, 0] B = [1, 0, 0]ᵀ
# [0, 1, 0] [0, 1, 0]ᵀ
# [0, 0, 1] [0, 0, 1]ᵀ
# BA = 单位矩阵(满秩!)

# 这就是LoRA的巧妙之处:
# 用两个低秩矩阵的乘积,可以表示秩为min(r,d)的任意矩阵!

表达能力分析:

  • r=1:只能表示一维的变化方向
  • r=8:适合简单风格迁移
  • r=16:通用场景推荐,平衡效果与效率
  • r=32~64:复杂任务,如知识注入
  • r=128+:极致追求效果,资源消耗大

二、Qwen模型的LoRA适配架构

2.1 Qwen注意力机制结构

Qwen2/2.5系列采用了GQA(Grouped Query Attention)架构,理解其结构是配置LoRA的前提:

Qwen注意力层结构
═══════════════════════════════════════════════════════════

输入Token序列

┌──────────────┴──────────────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ Q_proj │ │ K_proj │
│ (d→d) │ │ (d→d) │
└────┬────┘ └────┬────┘
│ │
▼ ▼
Query向量 Key向量(多个头共享)
(多个Query头) (GQA:组内共享)
│ │
└──────────┬──────────────────┘

┌───────────┐
│ Attention │
│ 计算 │
└─────┬─────┘

┌──────┴──────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ V_proj │ │ O_proj │
│ (d→d) │ │ (d→d) │
└─────────┘ └─────────┘

═══════════════════════════════════════════════════════════

FFN前馈网络
═══════════════════════════════════════════════════════════

┌────┴────┐
▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
│Gate │ │ Up │ │Down │
│_proj │ │_proj │ │_proj │
│d→4d │ │ d→4d │ │4d→d │
└──┬───┘ └──────┘ └──────┘
│ │
└─────┬──────┘

┌─────────┐
│ SiLU │
│ 激活 │
└────┬────┘

输出
═══════════════════════════════════════════════════════════

2.2 目标模块选择策略

LoRA可以注入到模型的不同位置,选择哪些模块对效果影响显著:

# ============================================
# Qwen模型LoRA模块配置对照表
# ============================================

# 策略1:最小配置(参数量最少)
minimal_config = {
"target_modules": ["q_proj", "v_proj"],
"可训练参数占比": "~0.1%",
"适用场景": "快速实验、风格简单迁移"
}

# 策略2:注意力层全覆盖(推荐默认)
attention_config = {
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"可训练参数占比": "~0.3%",
"适用场景": "通用微调、对话任务(推荐!)"
}

# 策略3:注意力+FFN(效果最好)
full_config = {
"target_modules": [
"q_proj", "k_proj", "v_proj", "o_proj", # 注意力
"gate_proj", "up_proj", "down_proj" # FFN
],
"可训练参数占比": "~0.8%",
"适用场景": "知识密集任务、复杂推理"
}

# 策略4:仅FFN(实验性)
ffn_only_config = {
"target_modules": ["gate_proj", "up_proj", "down_proj"],
"可训练参数占比": "~0.5%",
"适用场景": "知识编辑、遗忘问题"
}

2.3 Qwen2.5各规模推荐配置

# ============================================
# Qwen2.5 LoRA配置推荐
# ============================================

config_recommendations = {
# 0.5B ~ 1.5B 模型(小模型)
"qwen2.5-0.5b": {
"r": 16,
"alpha": 32,
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"dropout": 0.05,
"per_device_batch_size": 4,
"gradient_checkpointing": True
},

# 3B ~ 7B 模型(主流规模)
"qwen2.5-3b": {
"r": 16,
"alpha": 32,
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"dropout": 0.05,
"per_device_batch_size": 2,
"gradient_checkpointing": True
},
"qwen2.5-7b": {
"r": 16,
"alpha": 32,
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"dropout": 0.05,
"per_device_batch_size": 1, # 7B需要更大显存
"gradient_checkpointing": True,
"optim": "paged_adamw_8bit" # 分页优化器
},

# 14B+ 模型(建议用QLoRA)
"qwen2.5-14b": {
"r": 32, # 14B以上可适当提高rank
"alpha": 64,
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"dropout": 0.05,
"quantization": "4bit", # 必须量化
"per_device_batch_size": 1,
"gradient_checkpointing": True,
"optim": "paged_adamw_8bit"
},

# 72B 模型(必须QLoRA)
"qwen2.5-72b": {
"r": 64,
"alpha": 128,
"target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
"dropout": 0.05,
"quantization": "4bit",
"per_device_batch_size": 1,
"gradient_checkpointing": True,
"optim": "paged_adamw_8bit",
"batch_size": 1,
"gradient_accumulation_steps": 16 # 梯度累积弥补batch size
}
}

三、参数调优实战指南

3.1 调参决策树

LoRA调参决策树
═══════════════════════════════════════════════════════════

开始调参


┌────────────────┐
│ 效果不理想? │
└───────┬────────┘

┌────────┴────────┐
▼ ▼
是 否
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 检查数据质量 │ │ 检查过拟合? │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
数据OK? 训练loss↓ 训练loss≈验证loss
│ 但验证↑ │
▼ │ ▼
是 ▼ 增加dropout
│ ┌─────────────┐ 或增加数据
▼ │ 过拟合了! │
┌─────────┐ └──────┬──────┘
│ 增加rank │ │
└────┬────┘ ▼
│ ┌─────────────┐
▼ │ 欠拟合了? │
┌─────────┐ └──────┬──────┘
│ r=16→32 │ │
└────┬────┘ ▼
│ ┌─────────────┐
▼ │ 增加训练轮次 │
┌─────────┐ │ 或提高学习率 │
│ 还是不行 │ └─────────────┘
└────┬────┘


扩展target_modules
q,k,v,o → +FFN

═══════════════════════════════════════════════════════════

3.2 各参数详细解析

Rank(秩)调优

# Rank选择参考表
rank_guide = """
┌──────────┬────────────┬────────────────────────┐
│ Rank │ 参数量级 │ 适用场景 │
├──────────┼────────────┼────────────────────────┤
│ 4-8 │ ~50K │ 简单风格迁移、情绪分类 │
│ 16 │ ~130K │ 通用对话、指令跟随(推荐) │
│ 32 │ ~260K │ 复杂推理、知识注入 │
│ 64 │ ~520K │ 垂直领域专家、代码生成 │
│ 128+ │ ~1M+ │ 极限效果追求 │
└──────────┴────────────┴────────────────────────┘

调优建议:
1. 从r=16开始,这是效果与效率的甜蜜点
2. 复杂任务效果不好时,先试r=32而不是r=8
3. r翻倍,训练时间基本不变,但显存增加
4. QLoRA场景建议比标准LoRA更高rank(如r=32 vs r=16)
"""

Alpha(缩放因子)调优

# Alpha与Rank的关系
alpha_guide = """
核心原则:保持 α/r ≈ 2

推荐配置:
┌──────────┬──────────┬───────────┐
│ r │ α推荐 │ 缩放因子 │
├──────────┼──────────┼───────────┤
│ 8 │ 16 │ 2.0 │
│ 16 │ 32 │ 2.0 │ ← 推荐
│ 32 │ 64 │ 2.0 │ ← 推荐
│ 64 │ 128 │ 2.0 │
└──────────┴──────────┴───────────┘

特殊情况:
– α = r:保守配置,初始更新幅度小
– α = 2r:推荐配置,初始更新明显
– α >> r:激进配置,初始更新极强(慎用)

调优经验:
– 如果训练初期loss下降太快/震荡 → 降低α/r
– 如果训练很多epoch效果仍不明显 → 提高α/r
"""

Target Modules调优

# 模块选择经验
module_guide = """
Qwen2.5 Attention层解读:
– q_proj: Query投影,决定"关注什么"
– k_proj: Key投影,影响注意力分配
– v_proj: Value投影,控制信息传递内容
– o_proj: Output投影,聚合注意力结果

实验结论(基于多个任务平均):
1. 仅q_proj:参数量最少,但效果有限
2. q+v_proj:基本可用,适合简单任务
3. q+k+v+o:推荐,注意力全覆盖
4. +FFN:最佳效果,但参数量增加

特殊任务建议:
– 风格迁移:q_proj, v_proj
– 知识注入:q+k+v+o + FFN
– 指令遵循:q+k+v+o
– 代码生成:q+k+v+o + FFN(重要!)
"""

Dropout调优

# Dropout配置参考
dropout_guide = """
┌────────────┬────────────────────────────────────┐
│ dropout │ 适用场景 │
├────────────┼────────────────────────────────────┤
│ 0 │ 数据量>1万条,任务相对简单 │
│ 0.05 │ 数据量1000-10000条(推荐默认值) │
│ 0.1 │ 数据量<1000条,需要防过拟合 │
│ 0.2 │ 数据量<100条,复杂任务(慎用) │
└────────────┴────────────────────────────────────┘

注意事项:
– dropout越高,训练需要更多epoch
– 推理时不生效,不影响推理速度
– 过高的dropout(>0.3)可能损害学习
"""

3.3 学习率与训练策略

# 训练参数推荐
training_config = """
学习率配置:
┌─────────────────┬─────────────────────────────────┐
│ 组件 │ 学习率 │
├─────────────────┼─────────────────────────────────┤
│ LoRA参数 │ 1e-4 ~ 3e-4(推荐2e-4) │
│ 完整模型 │ 1e-5 ~ 5e-5(如果也训练原模型) │
│ 学习率调度 │ CosineAnnealing + Warmup │
└─────────────────┴─────────────────────────────────┘

Warmup配置:
– 建议总步数的3-5%作为warmup
– 对于1000步训练:warmup=30-50步
– 作用:防止初期更新过大导致不稳定

训练轮次:
– 简单任务:2-3 epoch
– 复杂任务:3-5 epoch
– 注意:LoRA过拟合比全参数微调更快

梯度累积:
– 当显存不足时,使用gradient_accumulation_steps
– 例如:per_device_batch_size=1, accumulation=4
等效batch_size=4,但显存占用不变
"""

四、完整代码实战

4.1 标准LoRA微调(Qwen2.5-7B)

"""
Qwen2.5-7B 标准LoRA微调
适用场景:单卡A100(80G) 或 多卡3090/4090
"""

import torch
from transformers import (
AutoModelForCausalLM,
AutoTokenizer,
TrainingArguments,
DataCollatorForLanguageModeling
)
from peft import LoraConfig, get_peft_model, TaskType
from datasets import load_dataset
from trl import SFTTrainer

# 模型路径
model_name = "Qwen/Qwen2.5-7B"

# 加载模型和分词器
print("加载模型…")
tokenizer = AutoTokenizer.from_pretrained(model_name)
tokenizer.padding_side = "right" # Qwen需要

model = AutoModelForCausalLM.from_pretrained(
model_name,
torch_dtype=torch.bfloat16, # 使用bf16节省显存
device_map="auto",
trust_remote_code=True
)

# LoRA配置 – 推荐配置
lora_config = LoraConfig(
r=16, # 秩选择
lora_alpha=32, # 缩放因子 = 2r
target_modules=[ # 目标模块
"q_proj", "k_proj",
"v_proj", "o_proj"
],
lora_dropout=0.05, # dropout
bias="none", # 不训练bias
task_type=TaskType.CAUSAL_LM,
inference_mode=False # 训练模式
)

# 应用LoRA
print("应用LoRA适配器…")
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 输出: trainable params: 19,407,424 || all params: 7,725,586,432 || trainable%: 0.2513

# 准备数据集
def format_instruction(example):
"""格式化训练数据"""
return {
"text": f"<|im_start|>user\\n{example['instruction']}<|im_end|>\\n"
f"<|im_start|>assistant\\n{example['output']}<|im_end|>"
}

# 加载并处理数据
dataset = load_dataset("json", data_files="train.jsonl")
dataset = dataset.map(format_instruction, remove_columns=dataset["train"].column_names)
dataset = dataset.train_test_split(test_size=0.1)

# 训练参数
training_args = TrainingArguments(
output_dir="./qwen-7b-lora",
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=4, # 有效batch=16
learning_rate=2e-4,
num_train_epochs=3,
warmup_ratio=0.03, # 3% warmup
lr_scheduler_type="cosine",
bf16=True, # bf16训练
logging_steps=10,
eval_strategy="steps",
eval_steps=100,
save_strategy="steps",
save_steps=500,
save_total_limit=3,
gradient_checkpointing=True, # 节省显存
optim="paged_adamw_32bit", # 分页优化器
report_to="tensorboard"
)

# 创建训练器
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset["train"],
eval_dataset=dataset["test"],
data_collator=DataCollatorForLanguageModeling(tokenizer, mlm=False)
)

# 开始训练
print("开始训练…")
trainer.train()

# 保存LoRA权重
trainer.save_model("./qwen-7b-lora-final")
print("训练完成!")

4.2 QLoRA微调(Qwen2.5-14B)

"""
Qwen2.5-14B QLoRA微调
适用场景:单卡A100(80G) 或 RTX 4090(24G) + QLoRA
"""

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
from peft import LoraConfig, get_peft_model, TaskType
from trl import SFTTrainer
from transformers import TrainingArguments

# QLoRA配置 – 4bit量化
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # Normal Float 4
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True, # 双重量化
)

# 加载模型
print("加载14B模型(4bit量化)…")
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2.5-14B",
quantization_config=bnb_config,
device_map="auto",
trust_remote_code=True,
torch_dtype=torch.bfloat16
)

# QLoRA配置 – 14B建议更高的rank
lora_config = LoraConfig(
r=32, # 14B建议r=32
lora_alpha=64, # 2r
target_modules=[
"q_proj", "k_proj", "v_proj", "o_proj"
],
lora_dropout=0.05,
bias="none",
task_type=TaskType.CAUSAL_LM,
inference_mode=False
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 输出: trainable params: 81,920,000 || all params: … || trainable%: 0.049

# 训练参数 – 针对14B优化
training_args = TrainingArguments(
output_dir="./qwen-14b-qlora",
per_device_train_batch_size=1, # 14B显存限制
gradient_accumulation_steps=16, # 累积到batch=16
learning_rate=2e-4,
num_train_epochs=3,
warmup_ratio=0.03,
lr_scheduler_type="cosine",
bf16=True,
logging_steps=10,
save_steps=500,
save_total_limit=3,
gradient_checkpointing=True,
optim="paged_adamw_8bit", # 8bit优化器
max_grad_norm=0.3, # 梯度裁剪
)

trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
)

trainer.train()

4.3 权重合并与推理

"""
LoRA权重合并与推理
"""

from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch

# 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2.5-7B",
torch_dtype=torch.bfloat16,
device_map="auto"
)

# 方式1:仅加载LoRA适配器(推理时动态合并)
print("方式1: 动态加载LoRA适配器…")
model = PeftModel.from_pretrained(base_model, "./qwen-7b-lora-final")

# 方式2:合并权重后保存(推理更快)
print("方式2: 合并权重…")
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./qwen-7b-merged")

# 方式3:与原模型比较
print("方式3: 不合并直接比较…")
print("=" * 50)
print("LoRA适配器文件大小:")
import os
lora_size = sum(os.path.getsize(f"./qwen-7b-lora-final/{f}")
for f in os.listdir("./qwen-7b-lora-final")
if f.endswith(".safetensors"))
print(f" {lora_size / 1024 / 1024:.2f} MB")

print("\\n原始模型文件大小:")
model_size = sum(os.path.getsize(f"./Qwen2.5-7B/{f}")
for f in os.listdir("./Qwen2.5-7B")
if f.endswith(".safetensors"))
print(f" {model_size / 1024 / 1024 / 1024:.2f} GB")

# 推理示例
print("\\n" + "=" * 50)
print("推理测试:")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B")

prompt = "请介绍一下LoRA微调技术的原理。"
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

outputs = model.generate(
**inputs,
max_new_tokens=512,
temperature=0.7,
top_p=0.9
)

response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"\\n问题: {prompt}")
print(f"回答: {response}")

五、常见问题与解决方案

5.1 显存问题

# 问题1: CUDA OOM
solutions_oom = """
解决方案(按优先级):
1. 启用梯度检查点
model.gradient_checkpointing_enable()

2. 使用QLoRA量化
BitsAndBytesConfig(load_in_4bit=True)

3. 减小batch_size
per_device_train_batch_size: 4 → 2 → 1

4. 启用梯度累积
gradient_accumulation_steps: 4 → 8

5. 使用分页优化器
optim="paged_adamw_8bit"

6. 减小序列长度
max_seq_length: 2048 → 1024
"""

5.2 效果问题

# 问题2: 训练效果不好
solutions_effect = """
排查步骤:

1. 检查数据质量
– 格式是否正确?
– 标签是否准确?
– 数据量是否足够?

2. 检查LoRA配置
– rank是否太低?(尝试16→32)
– alpha/r是否合适?(保持≈2)
– 目标模块是否覆盖足够?

3. 检查训练参数
– 学习率是否合适?(尝试1e-4~3e-4)
– warmup是否足够?(3-5%)
– epoch是否足够?(3-5)

4. 检查模型保存
– 合并时是否出错?
– 推理prompt格式是否正确?
"""

5.3 推理问题

# 问题3: 推理结果质量差
solutions_inference = """
可能原因与解决方案:

1. 响应格式混乱
– 检查prompt模板是否一致
– 添加system prompt约束格式

2. 重复生成
– 降低temperature (0.7→0.5)
– 提高top_p (0.9→0.95)
– 检查max_new_tokens是否过长

3. 回答与训练数据偏离
– 检查训练数据质量
– 可能需要增加训练epoch
– 检查学习率是否太高

4. 灾难性遗忘
– 任务冲突时使用多LoRA切换
– 或使用更小的rank
"""

六、最佳实践总结

# ============================================
# LoRA微调最佳实践检查清单
# ============================================

best_practices = """
□ 数据准备
├── 数据量: 建议1000条以上
├── 数据质量: 格式正确、标注准确、无噪声
└── 数据划分: 8:1:1 (train:val:test)

□ 模型选择
├── 7B以下: 标准LoRA, r=16
├── 7B-14B: QLoRA, r=32
└── 14B以上: QLoRA, r=64, 梯度累积≥8

□ LoRA配置
├── r: 从16开始,复杂任务用32-64
├── α: 设为2r
├── target: q,k,v,o至少全覆盖
├── dropout: 0.05 (默认)
└── bias: none (默认)

□ 训练配置
├── 学习率: 2e-4 (LoRA专用)
├── warmup: 3-5%
├── scheduler: cosine
├── epoch: 3-5
└── bf16: 开启

□ 显存优化
├── gradient_checkpointing: True
├── optim: paged_adamw_8bit
├── batch: 从小开始,不够再累积
└── max_seq: 按需设置,不宜过长

□ 保存与部署
├── 保存adapter和merged两种版本
├── 推理使用merged更快
├── 多任务用adapter切换
└── 定期备份训练状态
"""

print(best_practices)


赞(0)
未经允许不得转载:171主机测评 » 02_LoRA低秩适配原理与配置:Qwen模型的参数高效微调实战
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址