Simon Shi的小站

人工智能,机器学习, 强化学习,大模型,自动驾驶

0%

pHash/dHash
局部敏感哈希(LSH)
CNN/Clip特征提取
混合特征+质量评分

一、传统哈希算法(基于图像特征编码)

  1. ‌**感知哈希(pHash)**‌

    • 原理‌:将图像缩小至32x32像素→灰度化→离散余弦变换(DCT)→取左上角8x8区域→计算均值→生成64位二进制哈希值34。
    • 优势‌:对缩放、亮度变化鲁棒性强。
    • 应用‌:imagededup库核心算法之一5。
  2. ‌**差异哈希(dHash)**‌

    • 原理‌:缩放图像至9x8像素→灰度化→逐行比较相邻像素差值→生成二进制哈希46。
    • 优势‌:对图像边缘变化敏感,适合检测结构相似性。
  3. ‌**平均哈希(aHash)**‌

    • 原理‌:缩放图像至8x8像素→计算像素均值→生成64位二进制哈希67。
    • 缺点‌:对颜色变化敏感,易误判。
Read more »

Deep Image Matting

针对此前的图像抠图算法,在图像的前景和背景颜色相似或纹理复杂时表现不佳可能存在的问题:only use low-level features 和 lack high-level context。

提出以下创新:

一个深度卷积 encoder-decorder 网络,它将一个图像补丁和相应的 trimap 作为输入,预测图像的 alpha matte;

一个小型的卷积网络,用更准确的阿尔法值和更清晰的边缘来完善第一个网络的阿尔法预测。

此外,还创建了一个大规模的图像抠图数据集,包括 49,300 张训练图像和 1,000 张测试图像。
参考论文:Deep Image Matting

论文地址:https://arxiv.org/pdf/1703.03872

开源地址:https://sites.google.com/view/deepimagematting(数据需要通过邮箱[bprice@adobe.com]联系获得)

Read more »

模型效果评估,召回率

准确率

召回率

指标 定义与描述 示例场景
TP(True Positive) 真实类别为正类,且被模型正确预测为正类的样本数量。 疾病检测中,真实患病且被模型诊断为阳性的患者数量‌17。
TN(True Negative) 真实类别为负类,且被模型正确预测为负类的样本数量。 垃圾邮件分类中,正常邮件被正确识别为非垃圾邮件的数量‌46。
FP(False Positive)* 真实类别为负类,但被模型错误预测为正类的样本数量。 安防系统中,将正常行为误判为异常事件的数量(误报)‌17。
FN(False Negative 真实类别为正类,但被模型错误预测为负类的样本数量。 医学影像分析中,漏诊癌症病例的数量(漏报)‌37。

核心指标公式

指标名称 公式定义 应用场景
‌**准确率(Accuracy)**‌ Accuracy=(TP+TN)/(TP+TN+FP+TN​) 评估整体预测正确率,适用于类别均衡的数据集‌45
‌**召回率(Recall)**‌ Recall=TP/(TP+FN) 关注正样本的覆盖能力(如疾病筛查、搜索召回)‌16
‌**精确率(Precision)**‌ Precision=TP/(TP+FP) 关注预测结果的准确性(如垃圾邮件过滤)‌16
‌**F1值(F1-Score)**‌ F1=(2×Precision×Recall​) / (Precision+Recall) 综合精确率与召回率,用于类别不均衡数据‌56
‌**IOU(交并比)**‌ IOU=交集面积​ ‌/ 并集面积 目标检测中评估预测框与真实框的重叠度,值越接近1越好‌7

confusion_matrix

plot_confusion_matrix

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import numpy as np
import matplotlib.pyplot as plt

def plot_confusion_matrix(cm, classes, title='Confusion Matrix'):
plt.figure(figsize=(8,6))
plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)
plt.title(title, fontsize=14)
plt.colorbar()

tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation=45)
plt.yticks(tick_marks, classes)

# 添加数值标签
for i in range(cm.shape[0]):
for j in range(cm.shape[1]):
plt.text(j, i, format(cm[i, j], 'd'),
ha="center", va="center",
color="white" if cm[i, j] > cm.max()/2 else "black")

plt.ylabel('True Label', fontsize=12)
plt.xlabel('Predicted Label', fontsize=12)
plt.tight_layout()

# 示例数据
true_labels = [0,1,0,1,1,0,0,1]
pred_labels = [0,1,0,0,1,0,1,1]
classes = ['Negative', 'Positive']

# 生成混淆矩阵
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(true_labels, pred_labels)

# 绘图
plot_confusion_matrix(cm, classes)
plt.show()

Seaborn

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import seaborn as sns

def seaborn_confusion_matrix(cm, classes, title='Confusion Matrix'):
plt.figure(figsize=(8,6))
sns.heatmap(cm, annot=True, fmt='d', cmap='YlGnBu',
xticklabels=classes, yticklabels=classes)

plt.title(title, fontsize=14, pad=20)
plt.ylabel('True Label', fontsize=12)
plt.xlabel('Predicted Label', fontsize=12)
plt.xticks(rotation=45)
plt.yticks(rotation=0)

# 使用相同数据
seaborn_confusion_matrix(cm, classes)
plt.show()

Flask API

运行方式

1、Jenkins 安装docker,使用三方docker

  • 付费

2、jenkins安装docker客户端,

  • docker in docker,特权模式

3、直接使用宿主机的docker服务

  • 优点:方便,简单,直观

  • 确定:Jenkins可以全权管理所有的容器,包括自己,

docker如何运行:

  • docker-cli

  • docker.sock

  • docker-server

Jenkins挂载运行+docker

1
2
3
4
5
6
7
docker run \n 
-v /usr/bin/docker:/usr/bin/docker
    -v /var/run/docker.sock:/var/run/docker.sock
    -u root
    -d --name jenkins
    -p 8120:8080\
    jenkins/jenkins:jdk17

Demo1-Web自动化

基于docker的web部署

python + Git + Jenkins + Docker + Allure

pytest + selenium + Allure Web自动化测试

1
docker run --shm-size 2G ccr.ccs.tencentyun.com/beifang/ui_framework:v1 

生成报告(下载)

1、不知都 生成的结果在那

2、不知道 结果的权限?

docker –> host –> jenkins

A. Jenkins,挂载host目录

共享文件夹 777 jenkins_home/workspace

1
2
3
4
5
6
7
8
docker run \n 
-v /usr/bin/docker:/usr/bin/docker
-v /var/run/docker.sock:/var/run/docker.sock
-v ./jenkins_home:/var/jenins_home
-u root
-d --name jenkins
-p 8120:8080\
jenkins/jenkins:jdk17

B. 任务docker,挂在共享文件夹

1
2
3
4
mkdir -p allure_results && chown 777 allure_results

docker run -v /path/jenkins_home/workspace/$JOB_NAME/allure-results:/app/.allure_results \
--shm-size 2G image:v2

权限不足:

Demo2-前端部署

A.docker 容器部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
version: '3'
services:
docker_jenkins:
user: root
restart: always
image: jenkins/jenkins:lts # 指定服务所使用的镜像
container_name: jenkins # 容器名称
ports: # 对外暴露的端口定义
- 8080:8080
- 50000:50000
volumes: # 卷挂载路径
- /root/jenkins/jenkins_home/:/var/jenkins_home #冒号前为刚刚创建的路径,这里要写绝对路径
- /var/run/docker.sock:/var/run/docker.sock
- /usr/bin/docker:/usr/bin/docker
- /usr/local/bin/docker-compose:/usr/local/bin/docker-compose
docker_nginx:
restart: always
image: nginx
container_name: nginx
ports:
- 8090:80
- 80:80
- 433:433
volumes:
- /root/nginxcfg:/etc/nginx/conf.d #用我们创建的Nginx配置去替换容器中的默认配置,冒号前为我们创建的目录的路径
- /root/nginxcfg/logs:/var/log/nginx #nginx日志位置
- /root/xxx/xxx/xxx:/usr/share/nginx/html

nginx config

1
2
3
4
5
6
error_log  /var/log/nginx/error.log notice;
server{ # 简单的监听80端口,指定index位置
listen 80;
root /usr/share/nginx/html;
index index.html index.htm;
}

B. 配置

  1. 根据提示找到密码复制粘贴
    通过这个命令可以获取,/root/jenkins/jenkins_home为挂载目录
    cat /root/jenkins/jenkins_home/secrets/initialAdminPassword
  2. 安装推荐的插件
  3. 设置管理员账号

然后就可以愉快的使用Jenkins了

接着点击系统管理->插件管理,需要在Jenkins安装两个插件:

  1. 安装 Publish Over SSH 作用: 将构建后的编译产出发布到服务器
  2. 安装Generic Webhook Trigger Plugin作用:通用 Webhook 触发器构建

C. 新建一个Jenkins构建任务

  • 关联的git仓库有了推送事件之后触发的构建

  • 系统管理->全局工具配置,安装nodejs

  • 构建shell

  • node -v  #查看node,npm 版本
    npm -v 
    npm i  #npm安装项目所需依赖
    npm install hexo-cli -g  #npm安装hexo
    hexo clean  #hexo清除缓存文件和静态文件
    hexo g  #hexo生成静态文件
    tar -zcvf public.tar ./public  #压缩生成的静态文件目录
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

    ### 发布

    ```shell
    cd /root/yarbei/apps #进入文件所在目录
    mv yarbeiweb yarbeiweb-$(date +%Y%m%d-%H%M) #将旧的文件夹更名备份
    tar zxvf public.tar #解压public.tar
    mv public yarbeiweb #将解压后的文件夹改名
    rm -rf public.tar #删除压缩包

实践 hexo 编译发布

hexo编译环境打包

1
2
3
4
5
6
7
8
9
10
/dataraid/apps/webs/DockerFile

FROM docker.gh-proxy.com/jenkins/jenkins:lts-jdk17
USER root
RUN apt-get update && \
curl -sL https://deb.nodesource.com/setup_18.x | bash - && \
apt-get install -y nodejs && \
npm install -g hexo-cli hexo-deployer-git

USER jenkins

打包

1
2
/dataraid/apps/webs/DockerFile
docker build -t jenkins-hexo:latest -f DockerFile .

启动Jenkins容器

1
2
3
4
5
6
7
8
docker run \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v ./jenkins_home:/var/jenins_home \
-u root \
-d --name jenkins \
-p 8120:8080 \
jenkins/jenkins:jdk17

启动Hexo 编译容器(本地测试)

1
2
3
4
5
docker run  \
-v /dataraid/apps/docker_runs/jenkins/jenkins_home/workspace/blogs:/workspace/blogs \
-w /workspace/blogs \
jenkins-hexo:latest \
/bin/sh -c "npm install && hexo clean && hexo generate "

Jenkins job配置

webhook 触发器

1 Jenkins安装General Web Hook插件

2、Jenkins job配置 trigger

3、Jenkins 系统配置白名单

4、gitea 工程,配置hook

1
http://ip:port/generic-webhook-trigger/invoke?token=blog_hexo_auto"

5、gitea 配置app.ini (同机器部署,网络不通)

1
2
[webhook]
ALLOWED_HOST_LIST = *

参考

Gitlab+Jenkins+Docker+Harbor+K8s集群搭建CICD平台(持续集成部署Hexo博客Demo) - misakivv - 博客园

docker+Jenkins+nginx实现前端自动部署详细教程-腾讯云开发者社区-腾讯云

从0到1体验Jenkins+Docker+Git+Registry实现CI自动化发布

自动化发布静态页面 - Mrterrific - 博客园

  • git pull -> push to Host-A…

Gitea+K8s-Jenkins-master-slave(webhook钩子)_gitea web钩子-CSDN博客

docker+nginx+jenkins将hexo博客部署至云服务器

Unsloth DeepSeek R1动态量化部署方案

https://www.bilibili.com/video/BV1oePLezEZD/

https://kq4b3vgg5b.feishu.cn/wiki/UC0Yw4WzTix4fAkboPccaop1nvg

Unsloth DeepSeek R1动态量化部署方案
课程说明:
体验课内容节选自《2025大模型Agent智能体开发实战》完整版付费课程
体验课时间有限,若想深度学习大模型技术,欢迎大家报名由我主讲的《2025大模型Agent智能体开发实战》:

公开课全套学习资料,已上传至网盘(https://pan.baidu.com/s/1asgKKl1SZvMZTIYvkaD63w?pwd=af7y)

需要更系统深入学习大模型可扫码⬆️添加助教咨询喔~

一、DeepSeek R1部署方案综述

1.DeepSeek R1满血版模型高性能部署方案介绍

伴随着DeepSeek R1模型使用需求不断深化,如何才能部署更高性能的满血版DeepSeek R1模型,就成了很多应用场景下的当务之急。

受限于DeepSeek R1 671B(6710亿参数)的模型规模,通常情况下部署DeepSeek R1满血版模型需要1200G左右显存(考虑百人内并发情况),需要双节点8卡A100服务器才能运行(总成本约在260万-320万左右),而哪怕是INT 4半精度下,也需要至少490G显存,需要单节点8卡A100服务器才能运行。

DeepSeek R1和DeepSeek V3都是默认BF8精度,是一种低精度的浮点数格式。

BF8的全称是”Brain Floating Point”,由Google提出,主要用于大规模计算任务。与常见的16位浮点数(FP16)不同,BF8采用了8位尾数和8位指数的结构,能够在保证精度的同时减少计算和内存开销。

BF8的设计目标是减少计算量并保持数值稳定性,特别是在机器学习模型训练中,能在加速硬件上提供比FP32更好的性能。

在此情况下,如何以更少的成本获得尽可能好的模型性能——也就是如果进行DeepSeek R1的高性能部署,就成了重中之重。基本来说,目前的解决方案有以下三种:

1)【牺牲模型训练&微调性能】
采用“强推理、弱训练”的硬件配置:如选择国产芯片、英伟达A6000 ada图形显卡、或者采购DeepSeek一体机、甚至是选择MacMini集群等,都是不错的选择。

这些硬件模型训练性能较弱,但推理能力强悍,对于一些不需要进行模型训练和微调、只需要推理(也就是对话)的场景来说,是个非常不错的选择。

例如45万左右成本,就能购买能运行DeepSeek R1满血版模型的Mac Mini集群,相比购买英伟达显卡,能够节省很大一部分成本。

但劣势在于Mac M系列芯片并不适合进行模型训练和微调。

2)【牺牲模型推理性能】
采用DeepSeek R1 Distill蒸馏模型:DeepSeek R蒸馏模型组同样推理性能不俗,且蒸馏模型尺寸在1.5B到70B之间,可以适配于任何硬件环境和各类不同的使用需求。

3)配置说明
其中各蒸馏模型、各量化版本、各不同使用场景(如模型推理、模型高效微调和全量微调)下模型所需最低配置如下:

4)【牺牲模型推理速度】采用CPU+GPU混合推理模式。
由于采用了CPU执行计算任务,GPU的负载会大幅降低,整体硬件成本也会下降。

但是,毕竟CPU不适合进行深度学习计算,所以模型整体推理速度会很慢,并且无法进行模型训练。

llama.cpp项目介绍:https://github.com/ggml-org/llama.cpp

早在2023年3月,也就是Llama第一代模型开源不久,有一位C语言大神(Georgi Gerganov),在GitHub上发起了一个名为llama.cpp的项目,该项目非常夸张的用C语言编写了一整套深度学习底层张量计算库,极大程度降低了大模型等深度学习算法的计算门槛,并最终使得大模型可以在消费级CPU上运行。

llama.cpp现在已经成了大模型量化的标准解决方案,前面谈到的Q2、Q4、Q8等模型量化,都是借助llama.cpp完成的。这个神级项目,现在在GitHub上已经斩获了75k stars。

借助llama.cpp,可以使用纯CPU模式来运行DeepSeek R1模型,只不过此时需要大量的内存来加载模型权重,并且运行速度非常慢,不过硬件价格倒是很便宜。

比如网上甚至有500运行DeepSeek R1 Q4_K_M模型的组机方案,只不过采用纯CPU推理模式,每秒只能输出两个字符,而且不支持并发,一个300字的小作文,就得写个2、3分钟。

根据我们实测,哪怕是再CPU性能较强(志强4代)的情况下,推理速度约在3-4 tokens/s,且并发性能较差。

KTransformers

那能不能在CPU推理基础上,再借助一些GPU能力来加速呢?基于这个思路,清华大学团队和Unsloth团队,分别提出了可以同时借助CPU和GPU进行推理的DeepSeek R1部署方案。

KTransformers方案:https://github.com/kvcache-ai/ktransformers

清华大学发起的KTransformers(Quick Transformers)项目,可以借助R1模型的MoE架构特性,将专家模型的权重加载到内存上,并分配CPU完成相关计算工作,同时将MLA/KV Cache加载到GPU上,进而实现CPU+GPU混合推理。

经过这一技术创新,再志强4代CPU(或同性能CPU)+DDR5内存情况下,单并发能达到接近14 tokens/s。

此时不同模型内存需求如下:

《独家KTransformers技术实战》教学视频:https://www.bilibili.com/video/BV1kyAke9EBA/

AutoDL服务器,志强3代CPU+DDR4内存,单并发实测效果,接近4 tokens/s:

B站用户按照相同流程复现,升级硬件后,9654+DDR5实测效果,达到14tokens/s:

不过这套方案最大的问题在于,模型运行速度会大幅受到CPU性能影响,需要4代志强芯片才能达到10个以上token每秒,而且KTransformers对GPU性能挖掘不足,高并发场景下表现乏力,更适合小团队或个人使用。

Unsloth动态量化方案

https://github.com/unslothai/unsloth

相比之下,Unsloth提出的动态量化方案会更加综合一些,所谓动态量化的技术,指的是可以围绕模型的不同层,进行不同程度的量化,关键层呢,就量化的少一些,非关键层量化的多一些,最终得到了一组比Q2量化程度更深的模型组,分别是1.58-bit、1.73-bit和2.22-bit模型组。尽管量化程度很深,但实际性能其实并不弱。

此外,Unsloth提供了一套可以把模型权重分别加载到CPU和GPU上的方法,用户可以根据自己实际硬件情况,选择加载若干层模型权重到GPU上,然后剩下的模型权重加载到CPU内存上进行计算。

在实际部署的过程中,我们可以根据硬件情况,有选择的将一部分模型的层放到GPU上运行,其他层放在CPU上运行,从而降低GPU负载。最低显存+内存>=200G,即可运行1.58bit模型。

单卡4090(24G)时可加载7层权重在GPU上运行,40并发达到3.5tokens/s,双卡A100服务器能加载全部0到61层模型权重到GPU上,吞吐量达到140tokens/s,100并发时单人能达到14 tokens/s:

Unsloth方案优势:
和llama.cpp深度融合,直接通过参数设置即可自由调度CPU和GPU计算资源,灵活高效,且能够直接和ollama、vLLM、Open-WebUI等框架兼容。
深度挖掘GPU性能,并发量有保障。
相比KTransformers方案,Unsloth方案更适合有一定硬件基础(如4卡4090、双卡A100)的团队使用,能够保障一定的并发量。

DeepSeek R1硬件选配流程一览表

本节公开课我们将重点介绍Unsloth方案的部署流程,实现在两套服务器上部署并调用DeepSeek R1满血版模型(最低单卡4090即可进行调用),同时测试1.58 bit模型在纯CPU推理、CPU+GPU混合推理、以及纯GPU推理下性能与响应效率表现。

2、实验服务器配置说明

本次公开课尝试使用两套服务器,配置如下:

2.1 配置一:4卡4090服务器(实际最低一张GPU即可运行)

深度学习环境:PyTorch 2.5.1、Python 3.12(ubuntu22.04)、Cuda 12.4
硬件环境:
GPU:RTX 4090(24GB) * 4(实际只使用一张GPU)
CPU:64 vCPU Intel® Xeon® Platinum 8352V CPU @ 2.10GHz
内存:480G(至少需要382G)
硬盘:1.8T(实际使用需要200G左右)
可以考虑在AutoDL上租赁4卡4090服务器,480G内存,约14元每小时。

2.2 配置二:4卡H800服务器(模型纯GPU推理性能)

深度学习环境:PyTorch 2.5.1、Python 3.12(ubuntu22.04)、Cuda 12.4
硬件环境:
GPU:H800(80GB) * 4
CPU:80 vCPU Intel® Xeon® Platinum 8458P
内存:400G(至少需要382G)
硬盘:5T
其他更多相关参考资料

《DeepSeek R1本地部署流程》https://www.bilibili.com/video/BV19kFoe6Ef7/

《AutoDL快速入门》:https://www.bilibili.com/video/BV1bxB7YYEST/

二、Unsloth动态量化模型介绍简介

1、Unsloth动态量化模型简介与下载地址

为了让更多本地用户能够运行DeepSeek R1模型,Unsloth成功地将 DeepSeek 的 R1 671B 参数模型量化为 131GB大小,相比原始的 720GB减少了 80%,而且仍然保持很高的功能性。通过研究 DeepSeek R1 的架构,Unsloth成功地选择性地将某些层量化到更高的位数(比如 4bit),同时将大多数 MoE 层(如 GPT-4 中使用的层)量化为 1.5bit。简单地对所有层进行量化会完全破坏模型,导致无休止的循环和乱码输出。Unsloth的动态量化技术解决了这个问题。

Unsloth提供了 4 个动态量化版本。前 3 个版本使用重要性矩阵来校准量化过程(通过 llama.cpp 获取 imatrix),以允许更低位数的表示。最后一个 212GB 的版本是一个通用的 2bit 量化版本,没有进行任何校准。

MoE Bits 磁盘大小 类型 质量 链接
Down_proj 1.58-bit 131GB IQ1_S 一般
2.06/1.56-bit 1.73-bit 158GB IQ1_M 良好
2.22-bit 1.83-bit 183GB IQ2_XXS 更好
2.51-bit 2.51-bit 212GB Q2_K_XL 最佳

纯GPU推理下,1.58bit 量化版本适合 140GB+ 的 VRAM,用于快速推理(例如2 个 H100 80GB GPU,或者8卡4090服务器,总共192G显存),其吞吐量约为每秒 140 个 token,单用户推理为每秒 14 个 token。

这组模型可以在huggingface或魔搭社区上下载。

huggingface地址:https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main

魔搭社区地址:https://www.modelscope.cn/models/unsloth/DeepSeek-R1-GGUF/files

此外,如果没有 VRAM(GPU),Unsloth动态量化模型也支持CPU+GPU混合推理,不过速度可能会较慢。此时各模型运行所需RAM+VRAM要求如下:

DeepSeek-R1-UD-IQ1_M: RAM + VRAM ≥ 200 GB
DeepSeek-R1-Q4_K_M: RAM + VRAM ≥ 500 GB

36:(95+60)

21:(807+78)

2. 动态量化模型性能测试

为了测试所有量化模型,Unsloth没有依赖一般的基准测试,而是要求 DeepSeek R1 创建一个 Flappy Bird 游戏,并进行 3 次尝试(pass@3)。

我们根据 10 个标准来打分(比如使用随机颜色、随机形状,是否能在 Python 解释器中运行等)。

我们使用了种子值 3407、3408 和 3409,以及推荐的温度值 0.6。

以下是chat.deepseek.com 生成的示例:

而以下则是1.58bit 版本的结果。能够发现,尽管模型大小减少了 80%,我们的动态 1.58bit 版本仍然能够生成有效的输出:

类似地,如果不是动态量化,而是将所有层量化为 1.75bits(149GB),无限重复会停止,但结果完全不正确。所有输出都会显示完全黑屏。如果将所有层量化到 2.06bits(175GB),结果甚至比 1.58bit(131GB)动态量化还要差。关于分数总结(满分 10 分)和 Pass@3,Unsloth发现 1.58bit 131GB 版本在 Flappy Bird 基准测试中正确得分 69.2%,而 2bit 183GB 版本得分 91.7%。

模型大小 动态量化得分 模型大小 基 本量化得分
131GB 6.92 133GB 0
158GB 9.08 149GB 1.67
183GB 9.17 175GB 6.17

另一方面,非动态量化的模型表现非常差。将所有层量化为 1.58bits 得到 0% 的得分,即使在 175GB 的情况下,也仅能得到 61.7%,比动态量化还低。

3 动态量化模型量化过程

以下是Unsloth动态量化流程:

DeepSeek 的前 3 层是完全密集层,而非 MoE 层。回顾一下,MoE(专家混合)层允许我们增加模型中的参数数量,而不增加所需的 FLOP 数量,因为动态地将大多数条目掩码为 0,从而跳过了对零化条目的矩阵乘法运算。

1)前 3 层密集层使用了 0.5% 的所有权重,我们将这些层保持为 4 或 6bit。
2)MoE 层使用共享专家,使用了 1.5% 的权重,我们将其量化为 6bit。
3)我们可以将所有 MLA 注意力模块保持为 4 或 6bit,使用 <5% 的权重。我们应当量化注意力输出(3%),但最好保持较高精度。
4)down_proj 对量化最为敏感,尤其是在前几层。我们通过与 Super Weights 论文、我们的动态量化方法以及 llama.cpp 的 GGUF 量化方法进行对比,验证了这一点。因此,我们将前 3 层至 6 层 MoE down_proj 矩阵保持较高精度。例如,在 Super Weights 论文中,我们看到几乎所有不应量化的权重都在 down_proj 中:

关于为什么所有的“超级权重”或最重要的权重都在 down_proj 中的主要见解,是因为 SwiGLU(激活函数)实现了:

这意味着上层和门控投影的乘积会形成更大的数字,而 down_proj 需要将其缩小——这意味着量化 down_proj 可能不是一个好主意,尤其是在 Transformer 的早期层中。

5)我们应该将 embedding 和 lm_head 分别保持为 4bit 和 6bit。MoE 路由器和所有层归一化保持 32bit 精度。
6)这样,约 88% 的权重就是 MoE 权重!通过将它们量化为 1.58bit,我们可以大幅度缩小模型!
7)我们将我们的动态量化代码作为 fork 提供给 llama.cpp:github.com/unslothai/llama.cpp。
8)我们还利用了 Bartowski 的重要性矩阵来处理较低精度的量化。

三、Unsloth动态量化模型下载与运行

由于Unsloth动态量化模型和llama.cpp深度兼容,且提供了完整GGUF模型权重,因此可以使用各种主流方法进行调用,如使用llama.cpp命令进行调用、使用ollama、vLLM进行调用,并且也获得了如Open-WebUI等框架的支持,因此实际上R1动态量化模型可以有很多种运行方法,且各运行方法都支持从最小1.58 bit量化模型到Q8量化模型。

1、模型权重下载

公开课以1.58 bit模型、也就是UD-IQ1_S模型为例进行演示,其他模型只需要更换模型名称即可下载和运行。以下是各组模型运行所需最低内存+显存配置:

模型权重较大,总共约130G左右。若使用AutoDL,最快下载方法是开启学术加速并从Huggingface上进行下载。

AutoDL学术加速方法介绍:https://www.autodl.com/docs/network_turbo/

这里默认以AutoDL为基础实验环境进行介绍,默认已安装好CUDA、Miniconda等基础库。

下载流程如下:

安装huggingface_hub:
在命令行中输

1
pip install huggingface_hub

【可选】借助screen持久化会话

由于实际下载时间可能持续2-4个小时,因此最好使用screen开启持久化会话,避免因为关闭会话导致下载中断。

screen -S kt
1
创建一个名为kt的会话。之后哪怕关闭了当前会话,也可以使用如下命令

screen -r kt
1
若未安装screen,可以使用sudo apt install screen命令进行安装。
【可选】修改huggingface默认下载路径
在默认情况下,Huggingface会将下载文件保存在/root/.cache文件夹中,若想更换默认下载文件夹,则可以按照如下方式修改环境变量,或者在下载代码中设置下载路径。
首先在/root/autodl-tmp下创建名为HF_download文件夹作为huggingface下载文件保存文件夹(具体文件夹名称和地址可以自选):

1
cd /root/autodl-tmp mkdir HF_download

然后找到root文件夹下的.bashrc文件

在结尾处加上 export HF_HOME="/root/autodl-tmp/HF_download"

保存退出,输入

1
source ~/.bashrc

使环境变量生效。
下载模型权重
启动Jupyter

1
jupyter lab --allow-root

然后在开启的Jupyter页面中输入如下Python代码:

开启学术加速

1
2
3
4
5
6
7
8
9
10
import subprocess
import os

result = subprocess.run('bash -c "source /etc/network_turbo && env | grep proxy"', shell=True, capture_output=True, text=True)
output = result.stdout

for line in output.splitlines():
if '=' in line:
var, value = line.split('=', 1)
os.environ[var] = value

下载模型权重,只下载Q4_K_M部分权重

1
2
3
4
5
from huggingface_hub import snapshot_download
snapshot_download(
repo_id = "unsloth/DeepSeek-R1-GGUF",
local_dir = "DeepSeek-R1-GGUF",
allow_patterns = ["*Q4_K_M*"],)

完成下载数个小时,下载过程需要持续启动Jupyter服务,其中如果出现下载中断,重新运行下载代码即可继续下载。

然后即可在/root/autodl-tmp/DeepSeek-R1-GGUF/DeepSeek-R1-Q4_K_M中看到下载的GGUF格式模型权重:

【其他方案】使用魔搭社区进行下载
若是使用modelscope进行权重下载,则需要先安装魔搭社区

1
2
3
pip install modelscope
然后输入如下命令进行下载
modelscope download --model unsloth/DeepSeek-R1-GGUF --include '**UD-IQ1_S**' --local_dir /root/autodl-tmp/DeepSeek-R1-GGUF

2、借助Llama.cpp进行运行

由于Unsloth和llama.cpp深度融合,因此当我们下载完模型权重后,接下来即可直接使用llama.cpp调用模型权重进行推理和对话了。

2.1 llama.cpp下载与编译

llama.cpp项目主页:https://github.com/ggml-org/llama.cpp
由于llama.cpp是个C语言项目,因此实际调用过程需要先构建项目,然后设置参数进行编译,然后最终创建可执行文件(类似于脚本),再运行本地大模型。借助llama.cpp和Unsloth的模型权重,可以实现纯CPU推理、纯GPU推理和CPU+GPU混合推理。这里我们分别尝试三种运行模式。

目前市面上很多纯CPU推理的DeepSeek服务器,几乎都是使用上面的实现流程。

依赖下载
为了能够顺利的完成C语言项目的项目创建和代码编译,首先需要先进行相关依赖的下载:

1
2
apt-get update
apt-get install build-essential cmake curl libcurl4-openssl-dev -y

这条命令安装了一些常用的构建和开发工具,具体的每个部分的含义如下:
build-essential:安装一组构建必需的工具和库,包括:

  • 编译器(如 GCC)

  • make 工具

  • 其他一些常见的构建工具,确保你的系统能进行编译。

    • cmake:安装 CMake 工具,它是一个跨平台的构建系统,允许你管理项目的编译过程。

    • curl:安装 cURL 工具,它是一个命令行工具,用于通过 URL 发送和接收数据。它在很多开发场景中都很有用,尤其是与网络交互时。

    • libcurl4-openssl-dev:安装 libcurl 库的开发版本。它是 cURL 的一个库文件,允许你在编程中通过 cURL 发送 HTTP 请求。libcurl4-openssl-dev 是与 OpenSSL 配合使用的版本,提供了 SSL/TLS 加密支持,用于安全的 HTTP 请求。

    • llama.cpp源码下载
      若是AutoDL服务器,可以先开启学术加速:

1
source /etc/network_turbo

然后再进行下载:

1
git clone https://github.com/ggerganov/llama.cpp

准备好后,即可在服务器中看到llama.cpp项目文件夹
项目构建与编译
接下来需要使用cmake来构建项目文件:

1
2
cmake llama.cpp -B llama.cpp/build \
-DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=ON -DLLAMA_CURL=ON
  • cmake:运行 CMake 工具,用于配置和生成构建文件。

  • llama.cpp:指定项目的源代码所在的目录。在这个例子中,llama.cpp 是项目的根目录。

  • -B llama.cpp/build:指定生成构建文件的目录。-B 参数表示构建目录,

  • llama.cpp/build 是生成的构建目录。这是 CMake 将生成的文件存放的地方(例如 Makefile 或 Ninja 构建文件)。

  • 同时还指定了一些编译选项:
    禁用共享库(-DBUILD_SHARED_LIBS=OFF),生成 静态库。
    启用 CUDA 支持(-DGGML_CUDA=ON),以便在有 GPU 的情况下使用 GPU 加速。
    启用 CURL 库支持(-DLLAMA_CURL=ON),以便支持网络请求。

然后需要进一步进行编译:

1
2
cmake --build llama.cpp/build --config Release -j \
--clean-first --target llama-quantize llama-cli llama-gguf-split
  • –build llama.cpp/build:告诉 CMake 使用 llama.cpp/build 目录中的构建文件来执行构建过程。这个目录是在之前运行 cmake llama.cpp -B llama.cpp/build 命令时生成的,包含了所有构建所需的文件(例如 Makefile 或 Ninja 构建文件)。

  • –config Release:指定构建的配置为 Release 配置。
    Release 配置通常意味着启用更多的 优化,生成的程序运行速度较快,适合发布。
    在 CMake 中,通常有两种常见的构建配置:

  • Debug:用于调试版本,包含调试信息且没有做过多优化。

  • Release:优化后的发布版本,去除调试信息,运行时性能更高。

  • -j:表示并行构建,允许 CMake 使用多个 CPU 核心来加速构建过程。
    如果没有指定数字,CMake 会使用默认的并行级别,通常是可用的所有 CPU 核心。你也可以指定并行的作业数,例如 -j 8 表示使用 8 个并行作业进行编译。

  • –clean-first:表示在构建之前先清理掉之前的构建结果。这可以确保每次构建时都是从一个干净的状态开始,避免由于缓存或中间文件引起的编译错误。
    如果你之前运行过构建并且有问题,或者希望重新构建而不使用任何缓存文件,这个选项非常有用。

  • –target:指定构建的目标(target)。通常,一个项目会定义多个目标(比如库、可执行文件等),通过这个参数可以告诉 CMake 只编译特定的目标。
    llama-quantize:模型量化相关的目标。量化(quantization)是将模型的精度从浮点数降低到整数,从而减少内存占用和提高推理速度。
    llama-cli:用于运行模型或与用户交互。
    llama-gguf-split:文件合并merge the weights together

  • llama-batched                  llama-export-lora     llama-imatrix                  llama-lookup-stats    llama-qwen2vl-cli      llama-speculative-simple  test-c                       test-log                test-tokenizer-1-spm
    llama-batched-bench            llama-gbnf-validator  llama-infill                   llama-minicpmv-cli    llama-retrieval        llama-tokenize            test-chat                    test-model-load-cancel
    llama-bench                    llama-gemma3-cli      llama-llava-cli                llama-parallel        llama-run              llama-tts                 test-chat-template           test-quantize-fns
    llama-cli                      llama-gen-docs        llama-llava-clip-quantize-cli  llama-passkey         llama-save-load-state  llama-vdot                test-gguf                    test-quantize-perf
    llama-convert-llama2c-to-ggml  llama-gguf            llama-lookahead                llama-perplexity      llama-server           test-arg-parser           test-grammar-integration     test-rope
    llama-cvector-generator        llama-gguf-hash       llama-lookup                   llama-q8dot           llama-simple           test-autorelease          test-grammar-parser          test-sampling
    llama-embedding                llama-gguf-split      llama-lookup-create            llama-quantize        llama-simple-chat      test-backend-ops          test-json-schema-to-grammar  test-tokenizer-0
    llama-eval-callback            llama-gritlm          llama-lookup-merge             llama-quantize-stats  llama-speculative      test-barrier              test-llama-grammar           test-tokenizer-1-bpe
    
    1
    2
    3
    4
    5
    6
    7

    -

    复制可执行文件

    ```shell
    cp llama.cpp/build/bin/llama-* llama.cpp

将 所有生成的可执行文件 从构建目录 llama.cpp/build/bin/ 复制到项目的根目录 llama.cpp 下。这样可以更方便地在项目根目录下执行这些可执行文件,而无需每次都进入构建目录。
在准备完成后,接下来即可进行调用和推理测试了。

2.2 纯CPU推理流程

首先是纯CPU推理测试。此时系统只调用内存+CPU进行计算。我们这里使用服务器配置一,也就是480G内存+4卡4090服务器进行CPU推理测试。此时不会用到GPU,多并发情况下内存最多使用180G左右。实现流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
cd ./llama.cpp

./llama-cli \
--model DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 64 \
--prio 2 \
--temp 0.6 \
--ctx-size 512 \
--seed 3407 \
--n-gpu-layers 0 \
-no-cnv \
--prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"
  • –threads:CPU 核心数;

  • –ctx-size:输出的上下文长度;

  • –n-gpu-layers :需要卸载到 GPU 的层数,设置为0时代表完全使用CPU进行推理;

  • –temp:模型温度参数;

  • -no-cnv:不进行多轮对话;

  • –cache-type-k:K 缓存量化为 4bit;

  • –seed:随机数种子;

    实际运行效果如下所示:

最终对话效果如下所示:

对于Unsloth这组模型权重来说,只要内存够,哪怕是满血版DeepSeek R1模型也是可以运行的(需要1T内存)。只需要下载模型的时候选择BF16类型即可:https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-BF16。其他流程完全一样。

此外,也可以使用如下命令直接进行对话

1
2
3
4
5
6
7
8
9
./llama-cli \
--model /root/autodl-tmp/DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 64 \
--ctx-size 512 \
--prio 2 \
--temp 0.6 \
--seed 3407 \
--n-gpu-layers 0

run

1
2
3
4
./llama-cli \
--model /DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--ctx-size 512 \
--n-gpu-layers 35

2.3 CPU+GPU混合推理流程(单卡4090)

GPU显存分配流程
接下来进一步尝试CPU+GPU混合推理,我们只需要合理的设置–n-gpu-layers参数,即可灵活的将模型的部分层加载到GPU上进行运行。并且无需手动设置,llama.cpp会自动识别当前GPU数量以及可以分配的显存,自动将模型权重加载到各个不同的GPU上。

GPU加载模型权重层数计算
而某个设备到底能加载多少层模型权重,可以通过如下公式进行计算。

例如现在我是24G显存,且1.58bit模型权重大小为131GB,DeepSeek R1总共是0到61层,那么现在可以加载到我当前显卡的层数为:(24/131)*61-4=7.17,也就是最多设置–n-gpu-layers=7。

参考表:

Quant 文件大小 24GB GPU 80GB GPU 2x80GB GPU
1.58bit 131GB 7 33 所有61 层
1.73bit 158GB 5 26 57
2.22bit 183GB 4 22 49
2.51bit 212GB 2 19 32

混合推理流程
接下来尝试运行:

1
2
3
4
5
6
7
8
9
10
11
./llama-cli \
--model /root/autodl-tmp/DeepSeek-R1-GGUF/DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 64 \
--prio 2 \
--temp 0.6 \
--ctx-size 512 \
--seed 3407 \
--n-gpu-layers 7 \
-no-cnv \
--prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

此时对话效果如图所示:

总共占用23G显存:

能够看到推理速度略有提升。伴随着GPU上加载的权重越多,模型推理速度提升越大。不过这里需要注意的是,尽管单人推理时,24G显存只带来了不到1tokens/s的提升,但实际上此时模型吞吐量是大幅提升的, 模型的并行性能提升幅度较大。
需要注意的是,只要是带有CPU进行推理,那么CPU性能内存读取速度就是最大的瓶颈。相同服务器,在运行KTransformers的时候约3.8 tokens每秒。但经过了CPU和内存优化后,在不改变执行流程时候,KTransformers和Unsloth动态量化,推理速度都能够达到14 tokens/s左右。

2.4 CPU+GPU混合推理流程(4卡4090)

接下来继续尝试把更多的模型权重放在GPU上进行推理。这里以4卡4090为例,此时总显存为96,根据公式,此时可以在GPU上放总共约39层。

这里我们设置为35层进行实验:

1
2
3
4
5
6
7
8
9
10
11
./llama-cli \
--model DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 64 \
--prio 2 \
--temp 0.6 \
--ctx-size 512 \
--seed 3407 \
--n-gpu-layers 35 \
-no-cnv \
--prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

相比单卡24G显存,此时运行速度达到了5.78tokens/s,此时占用显存约92G

其他实验结果:

2.5 纯GPU推理流程

最后,我们更进一步,尝试把全部的模型权重都放在GPU上进行推理。这里我们启用第二套服务器配置,4卡H800服务器,总显存达到320G(实际上只用到140G)。根据官方说明,此时模型吞吐量将达到140tokens/s,单人能够达到14tokens/s。

以下是实际测试流程:

1
2
3
4
5
6
7
8
9
10
11
./llama-cli \
--model /DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
--cache-type-k q4_0 \
--threads 80 \
--prio 2 \
--temp 0.6 \
--ctx-size 512 \
--seed 3407 \
--n-gpu-layers 62 \
-no-cnv \
--prompt "<|User|>你好,好久不见,请介绍下你自己。<|Assistant|>"

此时推理速度约20 tokens/s。

3、服务化部署

1
2
3
4
5
6
7
./llama_server \
-m *.gguf \
-ngl 28 \
--cache-type-k q4_0

# 会启动一个类似web服务器的进程,默认端口号为8080,
# 这样就启动了一个 API 服务,可以使用 curl 命令进行测试。

curl call api

1
2
3
4
5
6
7
8
9
curl --request POST \
--url http://localhost:8080/completion \
--header "Content-Type: application/json" \
--data '{"prompt": "What color is the sun?","n_predict": 512}'

{"content":".....","generation_settings":
{"frequency_penalty":0.0,"grammar":"","ignore_eos":false,
"logit_bias":[],"mirostat":0,"mirostat_eta":0.10000000149011612,
"mirostat_tau":5.0,......}}

四、Unsloth动态量化+Ollama运行

1、ollama安装部署

原生支持使用Ollama调用本地模型进行推理,Ollama是一款大模型下载、管理、推理、优化集一体的强大工具,可以快速调用各类离线部署的大模型。Ollama官网:https://ollama.com/

1.1 【方案一】Ollama在线安装
在Linux系统中,可以使用如下命令快速安装Ollama

1
curl -fsSL https://ollama.com/install.sh | sh

该下载流程会受限于国内网络环境,下载过程并不稳定。

1.2 【方案二】Ollama离线安装
因此,在更为一般的情况下,推荐使用Ollama离线部署。我们可以在Ollama Github主页查看目前Ollama支持的各操作系统安装包:https://github.com/ollama/ollama/releases

若是Ubuntu操作系统,选择其中 ollama-linux-amd64.tgz下载和安装即可。

然后使用如下命令进行解压缩

1
mkdir ./ollama tar -zxvf ollama-linux-amd64.tgz -C ./ollama

解压缩后项目文件如图所示:

而在bin中,可以找到ollama命令的可执行文件。

此时,我们可以使用如下方式使用ollama:

1
cd ./bin ./ollama help

此处若显示没有可执行权限,可以使用如下命令为当前脚本添加可执行权限:

1
chmod +x ollama

而为了使用命令方便,我们也可以将脚本文件写入环境变量中。我们可以在主目录(root)下找到.bashrc文件:

然后在.bashrc 文件结尾写入 ollama/bin 文件路径:

1
export PATH=$PATH:/root/autodl-tmp/ollama/bin

保存并退出后,输入如下命令来使环境变量生效:

1
source ~/.bashrc

然后在任意路径下输入如下命令,测试ollama环境变量是否生效

1
ollama help

【可选】更换Ollama默认模型权重下载地址
接下来我们需要使用ollama来下载模型,但默认情况下,ollama会将模型下载到/root/.ollama文件夹中,会占用系统盘空间,因此,若有需要,可以按照如下方法更换模型权重下载地址。
此外无论是在线还是离线安装的ollama,都可以按照如下方法更换模型权重下载地址。还是需要打开/root/.bashrc文件,写入如下代码:

1
export OLLAMA_MODELS=/root/autodl-tmp/models

这里的路径需要改写为自己的文件地址

保存并退出后,输入如下命令来使环境变量生效:

source ~/.bashrc
测试环境变量是否生效

echo $OLLAMA_MODELS

启动ollama

接下来即可启动ollama,为后续下载模型做准备:

ollama start

注意,在整个应用使用期间,需要持续开启Ollama。

2、模型权重合并

由于ollama只支持读取单个GGUF格式权重,因此我们需要借助llama.cpp对3个模型权重进行合并:

然后使用如下命令进行权重合并

1
2
3
4
5
6
cd /root/autodl-tmp
mkdir DeepSeek-R1-UD-IQ1_S-merge
cd ./llama.cpp
./llama-gguf-split --merge /root/autodl-tmp/DeepSeek-R1-GGUF/ \
DeepSeek-R1-UD-IQ1_S/DeepSeek-R1-UD-IQ1_S-00001-of-00003.gguf \
merged_file.gguf

合并完成后:

3、借助Ollama调用 Unsloth动态量化模型

然后即可借助Ollama调用Unsloth动态量化模型了。这里我们首先需要将模型注册到ollama中,首先需要在合并文件夹内创建一个名为DeepSeekQ1_Modelfile的文件:

然后写入如下内容:

1
2
3
4
5
FROM ./merged_file.gguf
PARAMETER num_gpu 7
PARAMETER num_ctx 2048
PARAMETER temperature 0.6
TEMPLATE "<|User|>{{ .System }} {{ .Prompt }}<|Assistant|>"

各参数解释如下:

num_gpu:加载到GPU上的层数;
num_ctx:新生成最多多少个token;
temperature:模型温度参数;
template:模型提示词模板;
然后保存并退出,然后运行如下命令创建模型:

1
ollama create DeepSeek-R1-UD-IQ1_M -f DeepSeekQ1_Modelfile

然后即可查看模型是否成功注册:

ollama list

确认无误后即可运行模型

ollama run DeepSeek-R1-UD-IQ1_M --verbose

运行效果如下所示:

单卡4090时,基于ollama的加速,推理速度达到了6 tokens/s。而如果是双卡A100服务器,纯GPU推理能达到20tokens/s

五、Unsloth动态量化+Open-WebUI运行 最后,来介绍如何借助Open-WebUI来调用Unsloth动态量化模型。

首先需要安装Open-WebUI,官网地址如下:https://github.com/open-webui/open-webui。

可以直接使用在GitHub项目主页上直接下载完整代码包,并上传至服务器解压缩运行:

在准备好了Open-WebUI和一系列模型权重后,接下来我们尝试启动Open-WebUI,并借助本地模型进行问答。

首先需要设置离线环境,避免Open-WebUI启动时自动进行模型下载:

export HF_HUB_OFFLINE=1
1
然后启动Open-WebUI

open-webui serve
1
需要注意的是,如果启动的时候仍然报错显示无法下载模型,是Open-WebUI试图从huggingface上下载embedding模型,之后我们会手动将其切换为本地运行的Embedding模型。

然后在本地浏览器输入地址:8080端口即可访问:

若使用AutoDL,则需要使用SSH隧道工具进行地址代理

更多AutoDL相关操作详见公开课:《AutoDL快速入门与GPU租赁使用指南》|https://www.bilibili.com/video/BV1bxB7YYEST/

然后首次使用前,需要创建管理员账号:

然后点击登录即可。需要注意的是,此时Open-WebUI会自动检测后台是否启动了ollama服务,并列举当前可用的模型。稍等片刻,即可进入到如下页面:

然后即可开始进行对话:

更多关于大模型技术学习,欢迎报名由我主讲的《2025大模型Agent智能体开发实战》(2月DeepSeek强化班)https://whakv.xetslk.com/s/1tKbjV 进行更深度系统的学习哦~

《2025大模型Agent智能体开发实战》2025年2月班DeepSeek强化班特惠进行时,详细信息扫码添加助教,回复“大模型”,即可领取课程大纲&查看课程详情
————————————————

1

在当今人工智能领域,预训练的大模型已经成为推动技术发展的核心力量。然而,在实际项目中,我们往往会发现这些预训练模型虽然强大,但直接就去应用于一些特定的任务时,往往无法完全满足需求。这时,微调就成为了必不可少的一步。而在众多微调方法中,LORA全名(Low-Rank Adaptation)以高效性和实用性,逐渐成为了许多开发者训练模型的首选项。作为一名小有经验的咸鱼开发者,我深知在实际项目中高效的进行 LORA 微调,不仅能节省大量时间和资源,还能显著提升模型在各方面的性能。

本文我将会结合我的实战经验,带你探索 LORA 微调的全过程,从入门到入土,让你成为一名骨灰级玩家

一、环境与数据:微调的基础准备

**1.1 硬件与环境的配置

这里我推荐使用 NVIDIA RTX 30/40 系列 GPU(显存需要≥16GB),搭配32GB内存和500GB SSD存储。对于多机训练场景,这里建议提前配置 NCCL 通信库。软件环境建议通过 Conda 创建独立环境,按需选择 PyTorch 版本:

1
2
conda create -n lora python=3.10
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia

1.2 数据处理的工程化实践

数据清洗:去除噪声数据(比如乱码/重复文本),对不平衡数据进行重采样

高效预处理:使用 HuggingFace Datasets 库实现流水线处理

内存优化:对于超大规模数据集,我这里建议使用内存映射文件(MMAP)技术

1
2
3
4
5
6
7
from datasets import load_dataset
dataset = load_dataset("imdb") # 示例数据集
tokenized_data = dataset.map(lambda x:
tokenizer(x["text"], truncation=True, max_length=512),
batched=True,
num_proc=8 # 多进程加速
)

二、LORA 技术解析:轻量调参的艺术

2.1 低秩适应的数学本质

通过矩阵分解原理,将全参数更新 ΔW 分解为低秩矩阵 BA(B∈ℝ^{d×r}, A∈ℝ^{r×k}),其中秩 r≪min(d,k)。这种分解使参数量从 d×k 降至 r×(d+k),典型场景可减少 97% 的调参量。

2.2 实战配置策略

1
2
3
4
5
6
7
# 这里推荐使用 bitsandbytes 量化库降低显存占用
from transformers import BitsAndBytesConfig

quant_config = BitsAndBytesConfig(load_in_4bit=True,
bnb_4bit_use_double_quant=True)
model = AutoModel.from_pretrained("Llama-2-7b",
quantization_config=quant_config)

Lora调优

1
2
3
4
5
6
7
# LORA 参数调优指南
lora_config = LoraConfig(r=16, # 文本任务建议 8-32,视觉任务建议 32-64
lora_alpha=64, # α/r 控制缩放比例,通常设为 2r`
target_modules=["q_proj", "v_proj"], # Transformer 注意力模块
bias="lora_only", # 仅训练 LORA 层的偏置项
modules_to_save=["lm_head"] # 保留完整训练的关键输出层
)

三、训练过程的精细化控制

3.1 学习率的三阶段策略

预热阶段(前 10% steps):线性增长至 2e-5

稳定阶段:余弦退火调节

微调阶段(最后 5% steps):降至 1e-6

1
2
3
4
5
optimizer = AdamW(model.parameters(), 
lr=2e-5, weight_decay=0.01)
scheduler = get_cosine_schedule_with_warmup(optimizer,
num_warmup_steps=100,
num_training_steps=1000)

3.2 显存优化的三大技巧

梯度累积:training_args.gradient_accumulation_steps=4

混合精度训练:fp16=True(A100 建议使用 bf16)

激活检查点:model.gradient_checkpointing_enable()

四、关于过拟合的问题解答

4.1 什么是过拟合?

模型在训练集表现优异(如 98% 准确率),但在验证集/测试集显著下降(如 70%),这种现象称为过拟合。本质是模型过度记忆了训练数据中的噪声和特定模式,导致泛化能力下降导致模型过拟合.

4.2 过拟合的成因分析

数据层面:训练数据不足(<1k 样本)或多样性缺失

模型层面:参数量过大(如 7B 模型训练 1k 样本)

训练层面:迭代次数过多(如 100 epoch)或学习率过高

4.3 实战解决方案

数据增强:

NLP:同义词替换、回译增强、EDA(Easy Data Augmentation)

CV:MixUp、CutMix、随机擦除

正则化技术:

1
2
3
4
# 权重衰减
optimizer = AdamW(model.parameters(), lr=2e-5, weight_decay=0.01)
# 标签平滑
training_args = TrainingArguments(label_smoothing_factor=0.1)

1

‍早停法(Early Stopping):

监控验证集损失,当连续 3 个 epoch 无改善时终止训练

模型层面干预:

1
2
3
4
#冻结底层参数:
model.freeze_parameters(exclude=["lora_layers"])
#增加 Dropout 率:
config.attention_dropout=0.2

五、大模型部署的工业级实践

5.1 轻量化部署方案

1
2
3
4
5
6
# 模型合并与导出``
merged_model = model.merge_and_unload()
merged_model.save_pretrained("./lora_finetuned", safe_serialization=True)
# 使用 ONNX 加速
from transformers.convert_graph_to_onnx import convert
convert(framework="pt", model="./lora_finetuned", output="model.onnx")

5.2 服务化部署架构

1
2
3
4
5
6
A[客户端] --> B{Nginx 负载均衡}
B --> C[GPU 实例1: FastAPI]
B --> D[GPU 实例2: FastAPI]
C --> E[TRT 推理引擎]
D --> E
E --> F[Redis 缓存]

六、持续优化建议

使用 WandB 进行实验跟踪

尝试 DoRA(Weight-Decomposed LORA)提升效果

对于对话任务,建议采用 QLORA + 强化学习框架

1
2
3
4
5
# WandB 监控示例
import wandb
wandb.init(project="lora-tuning")
wandb.config.update({
"learning_rate": 2e-5, "batch_size": 32, "lora_rank": 16``})

原文链接:https://blog.csdn.net/2401_84495872/article/details/145965851

1

前置条件

安装 Dify 之前, 确保你的机器已满足最低安装要求:(Windows)

  • CPU >= 2 Core
  • RAM >= 4 GiB

1、安装Docker Desktop

部署Dify

1、源码下载

打开命令提示符(CMD)或 PowerShell,执行以下命令:

1
2
git clone https://github.com/langgenius/dify.git
cd dify

如果你的网络环境不好,无法直接克隆完整项目,可以试下以下的命令:

解释

1
2
3
4
5
6
# 缓冲区大小 
git config --global http.postBuffer 524288000
# 浅克隆
git clone --depth 1 https://github.com/langgenius/dify.git
# 获取所有历史
git fetch --unshallow

实在无法通过克隆下载的,可以直接压缩包进行解压。

Github 项目地址:GitHub - langgenius/dify: Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.

2、启动服务

  1. 进入 Dify 源代码的 Docker 目录
1
cd dify/docker
  1. 复制环境配置文件
1
cp .env.example .env
  1. 启动 Docker 容器

根据你系统上的 Docker Compose 版本,选择合适的命令来启动容器。你可以通过 docker compose version 命令检查版本

  • 如果版本是 Docker Compose V2,使用以下命令:
1
docker compose up -d
  • 如果版本是 Docker Compose V1,使用以下命令:
1
docker-compose up -d
  1. 运行命令后,等待所有服务启动完成,第一次运行需要点时间。

最后检查是否所有容器都正常运行:

3、访问平台

先前往管理员初始化页面设置设置管理员账户:http://localhost/install

创建应用

创建应用需要链接大模型,两种选择,1本地ollma部署2外部API接入(我使用的硅基流动的api接口) 

1、创建应用

2、配置应用

提示词等配置

3、测试&发布

4、密码重置

1
docker exec -it  docker-api-1 flask reset-password

参考

https://zhuanlan.zhihu.com/p/7851207343

Pygame

Pygame是被设计用来写游戏的python模块集合,Pygame是在优秀的SDL库之上开发的功能性包。使用python可以导入pygame来开发具有全部特性的游戏和多媒体软件,Pygame是极度轻便的并且可以运行在几乎所有的平台和操作系统上。

rl_games

rl_games是一个高性能强化学习库,实现了PPO、A2C等算法,支持NVIDIA Isaac Gym、Brax等环境的GPU加速训练。该库具备异步actor-critic、多智能体训练、自对弈等功能,可在多GPU上并行。rl_games提供Colab notebook示例便于快速上手,在多个基准测试中表现出色。作为一个功能丰富的强化学习工具,rl_games兼具高性能和易用性。