目录

确认系统版本

uname -m && cat /etc/*release

LLaMA-Factory安装并微调Deepseek-R1教程

检查GPU信息

首先,确认您的设备配备了 NVIDIA GPU:

lspci | grep -i nvidia

如果看到 NVIDIA 相关的输出,表示设备中存在 NVIDIA GPU。

更新系统并安装依赖

sudo yum update -y
sudo yum groupinstall -y "Development Tools"

禁用 Nouveau 驱动

Nouveau 是开源的 NVIDIA 驱动,为了安装官方驱动,需要先禁用 Nouveau:

# 创建禁用配置文件
sudo bash -c 'echo "blacklist nouveau" > /etc/modprobe.d/blacklist-nouveau.conf'
sudo bash -c 'echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf'

# 重新生成内核初始化文件
sudo dracut --force

# 重启系统
sudo reboot

重启后,验证 Nouveau 是否被禁用:

lsmod | grep nouveau

如果没有输出,表示禁用成功。

确认kenerl内核版本

内核版本kenerl与kernel-header和kernel-devel的版本需要一直

uname -r 查看系统当前版本

rpm -qa kernel-headers (查看kernel-headers版本)

rpm -qa kernel-devel (查看kernel-devel版本)

LLaMA-Factory安装并微调Deepseek-R1教程

如果不一致,需要将不一致的版本卸载掉

yum remove kernel-你自己的kernel版本(卸载kernel)
yum remove kernel-headers-你自己的kernel-devel版本(卸载kernel-headers)
yum remove kernel-devel-你自己的kernel-devel版本(卸载kernel-devel)

安装对应的版本

sudo yum install -y kernel-devel-$(uname -r) kernel-headers-$(uname -r)

安装Cuda

确认cuda版本

nvidia-smi

看到是12.4

https://developer.nvidia.com/cuda-12-4-0-download-archive?target_os=Linux&target_arch=x86_64&Distribution=CentOS&target_version=7&target_type=rpm_network

其它版本请在网上搜索

LLaMA-Factory安装并微调Deepseek-R1教程

安装Cuda Toolkit

版本列表:https://developer.nvidia.com/cuda-toolkit-archive

LLaMA-Factory安装并微调Deepseek-R1教程

LLaMA-Factory安装并微调Deepseek-R1教程

按照上方的安装命令安装,如果驱动已经安装就不需要安装了。

配置环境变量:

echo 'export PATH=/usr/local/cuda-12.4/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc

安装CuDNN

cuDNN列表:

https://developer.nvidia.com/rdp/cudnn-archive

选择和CUDA版本相符的最新版本

LLaMA-Factory安装并微调Deepseek-R1教程

LLaMA-Factory安装并微调Deepseek-R1教程

要登录才能下载

tar -xvJf cudnn-linux-x86_64-8.9.7.29_cuda12-archive.tar.xz

复制文件到 CUDA 目录

cd cudnn-linux-x86_64-8.9.7.29_cuda12-archive/
sudo cp lib/* /usr/local/cuda-12.4/lib64/
sudo cp include/* /usr/local/cuda-12.4/include/
sudo chmod a+r /usr/local/cuda-12.4/lib64/libcudnn*
sudo chmod a+r /usr/local/cuda-12.4/include/cudnn*.h

验证

cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

出现以下内容则为成功

LLaMA-Factory安装并微调Deepseek-R1教程

安装 Anaconda 并创建虚拟环境

Anaconda 版本列表:https://repo.anaconda.com/archive/

直接下载最新版

wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh

安装 Anaconda

bash Anaconda3-2024.10-1-Linux-x86_64.sh

接受license

Please answer 'yes' or 'no':'
>>> yes

设置安装目录

Anaconda3 will now be installed into this location:
/root/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below

[/root/anaconda3] >>> /opt/anaconda3

自动更新shell profile以便自动初始化conda

You can undo this by running `conda init --reverse $SHELL`? [yes|no]
[no] >>> yes

安装LLaMA-Factory

git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
conda create -n llama_factory python=3.10 -y
conda activate llama_factory
pip 
pip install -e ".[torch,metrics]" -i https://mirrors.aliyun.com/pypi/simple/

nohup python -m pip install -e ".[torch,metrics,bitsandbytes]" -i https://mirrors.aliyun.com/pypi/simple/ &

pip install -e .[torch,metrics,bitsandbytes] -i https://mirrors.aliyun.com/pypi/simple/

pip install modelscope>=1.11.0 -i https://mirrors.aliyun.com/pypi/simple/

LLaMA Board 可视化界面

llamafactory-cli webui

export USE_MODELSCOPE_HUB=1 ## 国内用户连不上huggingface,可以设置下从魔塔

pip install modelscope>=1.11.0 -i https://mirrors.aliyun.com/pypi/simple/

或者

设置 export HF_ENDPOINT=https://hf-mirror.com

微调测试

加载模型

LLaMA-Factory安装并微调Deepseek-R1教程

选择要训练的模型,我这边以deepseek r1 1.5B 测试,选择后点击加载模型

如果报错:llama factory We couldn't connect to 'https://huggingface.co'

要设置 export USE_MODELSCOPE_HUB=1,从魔塔下载模型,然后重启webui

设置数据集

1. 数据集格式

LLaMA-Factory 支持两种数据集格式:alpacasharegpt。根据您的需求,选择合适的格式。

  • Alpaca 格式

适用于指令监督微调、预训练、偏好训练等。以下是指令监督微调数据集的示例:

[
  {
    "instruction": "描述太阳系的结构。",
    "input": "",
    "output": "太阳系由太阳和围绕它运行的天体组成,包括行星、卫星、小行星等。",
    "system": "天文学助手",
    "history": [
      ["什么是太阳系?", "太阳系是由太阳和所有围绕它运行的天体组成的系统。"]
    ]
  }
]
  • ShareGPT 格式

适用于多轮对话、偏好训练等。以下是多轮对话数据集的示例:

[
  {
    "conversations": [
      {
        "from": "human",
        "value": "你好,能告诉我今天的天气吗?"
      },
      {
        "from": "gpt",
        "value": "当然,可以告诉我你所在的城市吗?"
      },
      {
        "from": "human",
        "value": "我在北京。"
      },
      {
        "from": "gpt",
        "value": "好的,北京今天晴,气温25摄氏度。"
      }
    ],
    "system": "天气助手"
  }
]

2. 配置 dataset_info.json

data/dataset_info.json 文件中,添加自定义数据集的描述,以便 LLaMA-Factory 正确加载和处理数据。

示例:

{
  "自定义数据集名称": {
    "file_name": "data.json",
    "formatting": "alpaca",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output",
      "system": "system",
      "history": "history"
    }
  }
}

请根据实际情况修改 file_namecolumns 的对应关系。

3. 数据集存放位置

将您的数据集文件(例如 data.json)放置在 data 目录下,确保路径与 dataset_info.json 中的 file_name 一致。

我这边是自定义了2个alpaca 类型的数据集 test_identity.json 和 ob_alpaca_dataset.json 用于测试

LLaMA-Factory安装并微调Deepseek-R1教程

LLaMA-Factory安装并微调Deepseek-R1教程

输出思维链(***)是 DeepSeek-R1 系列模型的一大特色,如果希望针对某个主题微调后的模型在回复时保留思维链,那么请准备带有思维链的训练数据。我上面的数据集是没有思维链信息的,仅供测试。

思维链训练数据示例:

[
    {
        "instruction": "请你写一段代码,实现大数据量下的快速排序功能。",
        "output": "<think>\n嗯,用户让我写一段代码,实现大数据量下的快速排序功能。首先,我得理解用户的需求。大数据量通常意味着数据量非常大,可能会影响传统快速排序的效率,或者用户希望代码在大数据情况下运行得更快、更稳定。\n\n快速排序本身是一种高效的排序算法,平均时间复杂度是O(n log n),但最坏情况下是O(n²)。不过,快速排序在大数据量下通常表现还是不错的,因为它在内存中操作,不需要额外的空间。所以,我应该考虑如何优化快速排序,特别是在大数据量的情况下。\n\n首先,我应该回顾一下快速排序的基本实现。快速排序通过选择一个基准元素,将数组分成两部分,小于基准的在左边,大于基准的在右边,然后递归排序这两部分。这个过程通常使用递归实现,但递归在大数据量下可能会导致栈溢出,所以可能需要改用迭代或者递归加尾部优化的方法。\n\n然后,考虑到大数据量,可能需要使用更高效的语言,比如C++,因为它比Python更快。不过,用户可能更倾向于使用Python,所以可能需要在Python中实现高效的快速排序。\n\n在Python中,快速排序的实现可能会遇到性能问题,因为Python本身的解释性解释器会影响速度。所以,可能需要使用一些优化技巧,比如选择一个好的基准元素,或者使用内置的函数来优化排序过程。\n\n另外,快速排序的性能优化通常包括减少递归调用的开销,使用迭代实现,或者选择一个更好的划分策略。比如,三划分或者使用中位数作为基准,可以减少递归的深度,从而减少栈溢出的风险,同时提高效率。\n\n我还应该考虑内存的使用。快速排序是原地排序,所以不需要额外的内存空间,但处理大数据量时,可能需要优化内存访问模式,避免频繁的数据交换,从而提高缓存效率。\n\n另外,可能需要使用一些高级的Python特性,比如使用生成器或者列表操作来优化排序过程。或者,可以考虑使用外部排序的方法,当数据量超过内存容量时,但用户的问题是关于大数据量下的快速排序,可能是指内存中的大数据,所以外部排序可能不是主要考虑。\n\n再者,快速排序的性能还与数据的初始状态有关。如果数据已经有序,快速排序的效率会降低,因为每次划分都会产生一个空的部分和一个长度为n-1的部分。这时候,可能需要使用三划分的方法,或者选择一个随机的基准,或者使用其他排序算法来处理这些情况。\n\n总结一下,我需要写一个高效的快速排序函数,可能需要考虑以下几点:\n\n1. 选择一个合适的基准元素,以减少递归深度和提高效率。\n2. 使用迭代实现,避免过多的递归调用,减少栈溢出的风险。\n3. 优化内存访问模式,提高缓存效率。\n4. 使用Python的内置函数和数据结构,尽可能提高性能。\n\n现在,我应该考虑如何实现这些优化。比如,在Python中,可以使用双指针法来实现快速排序,避免递归,改用迭代的方式。或者,可以使用递归,但增加尾部优化,或者使用尾递归的替代方案,虽然Python不支持尾递归优化,但可以通过其他方式模拟。\n\n另外,快速排序的性能还与数据的类型有关。如果数据是列表,可能需要将其转换为数组,或者使用更高效的数据结构,比如NumPy数组,但NumPy可能不在用户的要求范围内,所以可能需要避免使用。\n\n最后,我应该测试代码的性能,确保在大数据量下,排序速度足够快。可能需要使用一些基准测试,或者使用时间函数来测量排序的时间,确保优化后的代码在大数据量下表现良好。\n\n综上所述,我应该编写一个优化过的快速排序函数,使用双指针法,避免递归,或者使用更高效的语言特性,比如C++,但考虑到用户可能更倾向于Python,所以可能需要在Python中实现高效的快速排序,同时考虑优化策略。\n</think>\n\n在大数据量的情况下,快速排序可以通过一些优化措施来提高性能。以下是一个优化过的快速排序实现,使用双指针法和减少递归调用的开销:\n\n```python\ndef quick_sort(arr):\n    if len(arr) <= 1:\n        return arr\n\n    def partition low high:\n        pivot = arr[high]\n        while low <= high:\n            if arr[low] >= pivot:\n                low += 1\n            else:\n                arr[low], arr[high] = arr[high], arr[low]\n                high -= 1\n        return low\n\n    def quick_sort_helper low high:\n        if low >= high:\n            return\n        pivot_index = partition(low, high)\n        quick_sort_helper(low, pivot_index - 1)\n        quick_sort_helper(pivot_index + 1, high)\n\n    quick_sort_helper(0, len(arr) - 1)\n    return arr\n```\n\n### 优化措施:\n1. **减少递归开销**:将递归实现改为迭代实现,避免了递归调用的开销。\n2. **双指针法**:使用双指针法来实现快速排序,减少了内存交换的次数,提高了缓存效率。\n3. **减少递归深度**:通过选择一个合适的基准元素(这里使用最后一个元素作为基准),减少了递归深度,从而减少了栈溢出的风险。\n\n### 使用场景:\n这个实现适用于大数据量的排序任务,因为它减少了递归调用的开销,并且通过双指针法提高了缓存效率。\n\n### 示例使用:\n```python\nimport random\n\n# 生成一个大数据量的数组\ndata = list(range(1000000))\nrandom.shuffle(data)\n\n# 进行快速排序\nsorted_data = quick_sort(data)\n```\n\n这个实现在大数据量下表现良好,但需要注意的是,快速排序在最坏情况下时间复杂度仍然是O(n²),但这种情况在实际应用中非常罕见。"
    }
]

选择数据集后,可点击预览数据集,看是否正确

LLaMA-Factory安装并微调Deepseek-R1教程

设置训练参数

learning_rate:学习率,用于控制模型权重的调整幅度。

num_train_epochs:训练轮数,训练数据集被重复使用的次数,理论上越多越好,但是越大时间会越久,测试1-3轮,至少要几十轮。

per_device_train_batch_size:批处理大小,每个GPU在一次训练迭代中处理的样本数量。较大的批次大小可以提高效率,也会增加显存的需求。

gradient_accumulation_steps:梯度累积,梯度累积步骤数。

cutoff_len :截断长度,模型在一次训练中处理的输入数据的最大token长度。显存不够可降低

lora_rank:LoRA 秩,LoRA 矩阵的秩大小。LoRA维度。

lora_alpha:LoRA 缩放系数,LoRA权重。

lora_dropout:LoRA 随机丢弃,LoRA训练的丢弃率。通过在训练过程中随机丢弃神经元,来防止神经网络过拟合。

loraplus_lr_ratio :LoRA+ 学习率比例(λ = ηB/ηA)。ηA, ηB分别是adapter matrices A与B的学习率。相比于 LoRA,LoRA+可以为过程中的关键部分使用不同的学习率来实现更好的性能和更快的微调,而无需增加计算需求。当lorap_lr_ratio设为0时,表示使用普通的LoRA而非LoRA+。

开始训练

LLaMA-Factory安装并微调Deepseek-R1教程

模型评估

刷新页面,选择检查点路径,为刚刚训练完成的LoRA权重,然后选上数据集,填写输出目录,点击开始。

LLaMA-Factory安装并微调Deepseek-R1教程

微调模型测试

检查点选择训练的结果,也就是训练时设置的输出目录

LLaMA-Factory安装并微调Deepseek-R1教程

训练后,发现效果不好,可以考虑以下原因

LLaMA-Factory安装并微调Deepseek-R1教程

调整训练参数,如果训练数据集样本太少,可以尝试提高训练轮次和增大学习率

我测试的数据集就比较少,最终的参数如下:

llamafactory-cli train \
    --stage sft \
    --do_train True \
    --model_name_or_path deepseek-ai/DeepSeek-R1-Distill-Llama-8B \
    --preprocessing_num_workers 16 \
    --finetuning_type lora \
    --template deepseek3 \
    --flash_attn auto \
    --dataset_dir data \
    --dataset alpaca_zh_demo_olm \
    --cutoff_len 2048 \
    --learning_rate 0.0002 \
    --num_train_epochs 6.0 \
    --max_samples 100000 \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 2 \
    --lr_scheduler_type cosine \
    --max_grad_norm 1.0 \
    --logging_steps 5 \
    --save_steps 100 \
    --warmup_steps 0 \
    --packing False \
    --report_to none \
    --output_dir saves/DeepSeek-R1-8B-Distill/lora/train_deepseek_r1_8b-2025-02-21-17-15-35 \
    --bf16 True \
    --plot_loss True \
    --trust_remote_code True \
    --ddp_timeout 180000000 \
    --include_num_input_tokens_seen True \
    --optim adamw_torch \
    --adapter_name_or_path saves/DeepSeek-R1-8B-Distill/lora/train_deepseek_r1_8b-2025-02-21-17-15-35 \
    --lora_rank 8 \
    --lora_alpha 16 \
    --lora_dropout 0 \
    --lora_target all

调整参数后重新训练

LLaMA-Factory安装并微调Deepseek-R1教程

微调前:

LLaMA-Factory安装并微调Deepseek-R1教程

微调后:

LLaMA-Factory安装并微调Deepseek-R1教程

安装unsloth

4*RTX 4090 24G 显卡,尝试微调,训练时显存爆了(后续发现不支持多卡,放弃)

依赖 bitsandbytes,需要预先安装一下

pip install -e .[bitsandbytes]

安装命令,会根据cuda版本和torch版本来安装对应的版本。

LLaMA-Factory安装并微调Deepseek-R1教程

官方贴心的提供了一个py脚本可以获取最佳的pip安装命令,执行下面的命令,就会返回安装命令

wget -qO- https://raw.githubusercontent.com/unslothai/unsloth/main/unsloth/_auto_install.py | python -

LLaMA-Factory安装并微调Deepseek-R1教程

unsloth github

pip install "unsloth[cu124-ampere-torch260] @ git+https://ghfast.top/https://github.com/unslothai/unsloth.git"

使用上面命令安装报错:

ERROR: Could not find a version that satisfies the requirement bitsandbytes>=0.45.1; extra == "cu124-ampere-torch260" (from unsloth[cu124-ampere-torch260]) (from versions: 0.31.8, 0.32.0, 0.32.1, 0.32.2, 0.32.3, 0.33.0, 0.33.1, 0.34.0, 0.35.0, 0.35.1, 0.35.2, 0.35.3, 0.35.4, 0.36.0, 0.36.0.post1, 0.36.0.post2, 0.37.0, 0.37.1, 0.37.2, 0.38.0, 0.38.0.post1, 0.38.0.post2, 0.38.1, 0.39.0, 0.39.1, 0.40.0, 0.40.0.post1, 0.40.0.post2, 0.40.0.post3, 0.40.0.post4, 0.40.1, 0.40.1.post1, 0.40.2, 0.41.0, 0.41.1, 0.41.2, 0.41.2.post1, 0.41.2.post2, 0.41.3, 0.41.3.post1, 0.41.3.post2, 0.42.0)
ERROR: No matching distribution found for bitsandbytes>=0.45.1; extra == "cu124-ampere-torch260"

更新 bitsandbytes,发现最高只能安装到0.42版本,查看 bitsandbytes 0.45 的安装要求发现是自己 glibc 版本太低,我的版本 glibc 才 2.17

查看 glibc 版本: ldd --version

LLaMA-Factory安装并微调Deepseek-R1教程

升级glibc:《Linux运维总结:Centos7.6之glibc2.17版本升级至2.31》

升级 glibc 为高危操作,建议先在虚拟机中测试后再执行

再次重新执行 unsloth 安装,就安装成功啦。

参考资料

cuDNN安装过程记录

CentOS nvidia+cuda+cudnn 安装

centos7.9 安装nvidia驱动 及 CUDA Toolkit 开发工具包

centos7安装显卡驱动+CUDA+CUDNN