机战私服层层封锁穿墙vLLM、ollama方式部署本地大模型(单机)

1.安装显卡驱动 1.1 查看显卡类型

PCI/PCIe 总线的硬件设备信息:

[root@localhost ~]# lspci | grep -E "NVIDIA|VGA" 02:00.0 VGA compatible controller: Huawei Technologies Co., Ltd. Hi171x Series [iBMC Intelligent Management system chip w/VGA support] (rev 01) 3b:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) 3c:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) 5e:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) 86:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) 87:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) af:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1) d8:00.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)

可以看到显卡类型:NVIDIA Corporation TU104GL [Tesla T4] (rev a1)

查看系统类型

cat /etc/os-release

终端输出信息:

NAME="Kylin Linux Advanced Server" VERSION="V10 (Halberd)" VERSION_ID="V10" PRETTY_NAME="Kylin Linux Advanced Server V10 (Halberd)" ANSI_COLOR="0;31"

查看系统架构

lscpu 1.2 下载显卡驱动

NVIDIA显卡下载官网地址:Download The Official NVIDIA Drivers | NVIDIA

根据显卡类型、系统平台下载显卡驱动,机战私服层层封锁穿墙下载页面选择的下载配置参考如下:

名称 选择值
Select Product Category   选择 Data Center /Tesla  
Select Product Series   选择 T-Series  
Select Product   选择 Tesla T4  
Select Operating System   选择 Linux 64-bit  
Any CUDA Toolkit Version   (可)选择 12.8  
English(US)   默认就选英文(不推荐中文)  

注意:Operating System请选择Linux 64-bit,下载后的文件名称:NVIDIA-Linux-x86_64-570.86.15 .run,是.run格式的

1.3 kernel-devel

安装与当前内核版本匹配的 kernel-devel 包:

yum install "kernel-devel-uname-r == $(uname -r)"

重启:

reboot 1.4 禁用Nouveau驱动

参考:禁用nouveau驱动 - 华为鲲鹏服务器 GPU卡操作指导书 03 - 华为

防止冲突,禁用Nouveau驱动;查看命令:

lsmod | grep nouveau

如果终端输出信息中包含Nouveau驱动信息,说明Nouveau驱动已安装,则需要禁用Nouveau驱动,禁用步骤如下:

编辑blacklist.conf文件

vi /etc/modprobe.d/blacklist.conf

编辑内容:

# 注释掉blacklist nvidiafb (# blacklist nvidiafb) # 添加下面2行 blacklist nouveau options nouveau modeset=0

执行以下命令,备份并新建一个initramfs:

mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak dracut -v /boot/initramfs-$(uname -r).img $(uname -r)

重启:

reboot 1.5 禁用GUI (图形化)

命令:

systemctl set-default multi-user.target

设置为 multi-user.target 后,系统将启动到命令行界面,多个用户可以同时登录,但不启动图形桌面环境。这个模式适用于服务器环境或需要稳定命令行操作的场景,不需要图形用户界面的干扰。

重启:

reboot

其他命令:

# 如果有需要,执行下面命令恢复默认图形界面 systemctl set-default graphical.target 1.6 安装显卡驱动

参考:

手动安装GPU加速型ECS的Tesla驱动_弹性云服务器 ECS_华为云

在Centos上为Tesla T4显卡安装NVIDIA驱动以及cuda和cudnn_t4显卡驱动-CSDN博客

命令:

# 添加可运行权限 chmod +x NVIDIA-Linux-x86_64-570.86.15.run # 安装 sh NVIDIA-Linux-x86_64-570.86.15.run

安装后,重启:

reboot

查看显卡信息:

nvidia-smi # watch -n 1 nvidia-smi (终端每秒刷新显卡信息)

输出信息参考如下:

(vllm) [root@localhost bin]# nvidia-smi Thu Feb 20 23:52:41 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 570.86.15 Driver Version: 570.86.15 CUDA Version: 12.8 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 Tesla T4 Off | 00000000:3B:00.0 Off | 0 | | N/A 69C P0 30W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 1 Tesla T4 Off | 00000000:3C:00.0 Off | 0 | | N/A 70C P0 28W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 2 Tesla T4 Off | 00000000:5E:00.0 Off | 0 | | N/A 69C P0 31W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 3 Tesla T4 Off | 00000000:86:00.0 Off | 0 | | N/A 73C P0 32W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 4 Tesla T4 Off | 00000000:87:00.0 Off | 0 | | N/A 75C P0 33W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 5 Tesla T4 Off | 00000000:AF:00.0 Off | 0 | | N/A 67C P0 30W / 70W | 1MiB / 15360MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 6 Tesla T4 Off | 00000000:D8:00.0 Off | 0 | | N/A 73C P0 32W / 70W | 1MiB / 15360MiB | 5% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | No running processes found | +-----------------------------------------------------------------------------------------+ 1.7 cuda-toolkit安装

下载地址: https://developer.nvidia.com/cuda-toolkit-archive

根据系统信息选择,参考选择如下:

Operating System --> 选择`Linux` Architecture --> 选择`x86_64` Distribution --> 选择`KylinOS` Version --> 选择`10` Installer Type --> 选择`runfile(local)`

安装命令:

wget https://developer.download.nvidia.com/compute/cuda/12.8.0/local_installers/cuda_12.8.0_570.86.10_linux.run chmod +x cuda_12.8.0_570.86.10_linux.run sudo sh cuda_12.8.0_570.86.10_linux.run

安装成功结果:

[root@localhost nvidia_driver]# ./cuda_12.8.0_570.86.10_linux.run =========== = Summary = =========== Driver: Not Selected Toolkit: Installed in /usr/local/cuda-12.8/ Please make sure that - PATH includes /usr/local/cuda-12.8/bin - LD_LIBRARY_PATH includes /usr/local/cuda-12.8/lib64, or, add /usr/local/cuda-12.8/lib64 to /etc/ld.so.conf and run ldconfig as root To uninstall the CUDA Toolkit, run cuda-uninstaller in /usr/local/cuda-12.8/bin ***WARNING: Incomplete installation! This installation did not install the CUDA Driver. A driver of version at least 570.00 is required for CUDA 12.8 functionality to work. To install the driver using this installer, run the following command, replacing <CudaInstaller> with the name of this run file: sudo <CudaInstaller>.run --silent --driver Logfile is /var/log/cuda-installer.log

添加环境变量:

vim ~/.bashrc

编辑内容如下:

# cuda-toolkit export PATH=/usr/local/cuda-12.8/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-12.8/lib64:$LD_LIBRARY_PATH export CUDA_HOME=/usr/local/cuda-12.8

生效配置的环境变量:

source ~/.bashrc

验证安装:

nvcc --version # 输出内容有 Cuda compilation tools, release 12.8, V12.8.61 类似这种的,代表安装好了。 1.8 cuDNN安装

参考:
Linux-CUDA 和cuDNN安装 - 知乎

下载地址:https://developer.nvidia.com/rdp/cudnn-archive

解压文件:

tar -xvf cudnn-linux-x86_64-8.9.7.29_cuda11-archive.tar.xz

将解压后的头文件和库复制到cuda目录中:

# 切换到 cudnn 安装目录 cd cudnn-linux-x86_64-8.9.7.29_cuda11-archive # 将 cuDNN 的头文件复制到 CUDA 的 include 目录下 sudo cp include/cudnn* /usr/local/cuda/include # 将 cuDNN 的库文件复制到 CUDA 的 lib64 目录下 sudo cp lib/libcudnn* /usr/local/cuda/lib64 # 修改文件权限,确保所有用户都可以读取 cudnn 头文件和库文件 sudo chmod a+r /usr/local/cuda/include/cudnn* /usr/local/cuda/lib64/libcudnn*

cuDNN安装完成,查看安装的版本:

# 查看 cudnn_version.h 文件中的 CUDNN_MAJOR 宏定义,并显示该行以及后续的两行 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

终端显示:

#define CUDNN_MAJOR 8 #define CUDNN_MINOR 9 #define CUDNN_PATCHLEVEL 7 -- #define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL) 1.9 torch-CUDA虚拟环境安装

参考:Linux-CUDA 和cuDNN安装 - 知乎

2. 下载离线模型

如果已经用迅雷或者其他方式已经下载好了离线的模型库文件,或者有更好的下载离线模型方式,可以略过下载离线模型步骤。

2.1 配置镜像加速

编辑文件:

vim /etc/profile

添加如下内容:

# huggingface.co 加速 export HF_ENDPOINT=https://hf-mirror.com

生效:

source /etc/profile 2.2 创建虚拟环境

venv 是 Python 的内置模块,用于创建虚拟环境。虚拟环境允许你在项目中隔离依赖包,避免与全局环境中的其他项目产生冲突。使用虚拟环境可以确保项目的依赖独立,易于管理和部署。以下步骤请在python3虚拟环境中执行。

创建虚拟环境:

# 切换路径 cd /usr/local/python3/bin # 退出conda环境 conda deactivate # 创建虚拟环境 python3 -m venv my-environment 2.3 下载模型到本地

激活虚拟环境:

source my-environment/bin/activate

虚拟环境中执行:

pip install -U huggingface_hub

利用huggingface-cli下载模型语法:

huggingface-cli download --resume-download {填写huggingface.co官网的model name} --local-dir {模型的保存路径}

创建模型保存目录:

mkdir -p /home/data/models/DeepSeek-R1-Distill-Qwen-1.5B

下载模型到本地:

huggingface-cli download --resume-download deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B --local-dir /home/data/models/DeepSeek-R1-Distill-Qwen-1.5B

退出虚拟环境命令:

deactivate 3. 安装Deepseek 3.1 ollama方式 3.1.1 安装

Linux平台安装命令:

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

脚本内容在线参考:ollama/docs/linux.md at main · ollama/ollama · GitHub

3.1.2 配置ollama自启动

编辑systemd自启动文件:

vim /etc/systemd/system/ollama.service

编辑参考内容:

[Unit] Description=ollama Service After=network-online.target [Service] ExecStart=/usr/bin/ollama serve Environment="PATH=/usr/local/sbin:/usr/sbin:/usr/local/bin:/usr/bin:/bin:/root/bin" Environment="OLLAMA_MODELS=/home/data/ollama/models" [Install] WantedBy=default.target 3.1.3 运行Deepseek 3.1.3.1 方式一

直接使用使用ollama命令,运行Deepseek:

ollama run deepseek-r1:{参数数量}b 3.1.3.2 方式二

使用下载到本地的模型进行部署

3.1.3.2.1 配置加速 # 编辑文件 vim /etc/profile # huggingface加速 export HF_ENDPOINT=https://hf-mirror.com # 生效 source /etc/profile 3.1.3.2.2 下载模型库

创建模型保存的目录:

mkdir -p /home/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B

创建虚拟环境:

python3 -m venv my-environment

激活虚拟环境:

source my-environment/bin/activate

虚拟环境中执行:

# 进入虚拟环境中执行 pip install -U huggingface_hub

虚拟环境中执行:

# 下载模型库 huggingface-cli download --resume-download {复制huggingface.co模型的名称} --local-dir /home/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B 3.1.3.2.3 转换并运行

把离线下载好的deepseek本地模型转换成ollama能用的,操作步骤如下:

切换到模型库下载目录:

cd /home/yyj/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B

创建ollama构建镜像的文件:

vim /home/yyj/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B/Modelfile

Modelfile内容如下:

# Modelfile generated by "ollama show" # To build a new Modelfile based on this, replace FROM with: # FROM {需要替换成离线模型库保存的位置} FROM /home/yyj/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B TEMPLATE """{{- if .System }}{{ .System }}{{ end }} {{- range $i, $_ := .Messages }} {{- $last := eq (len (slice $.Messages $i)) 1}} {{- if eq .Role "user" }}<|User|>{{ .Content }} {{- else if eq .Role "assistant" }}<|Assistant|>{{ .Content }}{{- if not $last }}<|end▁of▁sentence|>{{- end }} {{- end }} {{- if and $last (ne .Role "assistant") }}<|Assistant|>{{- end }} {{- end }}""" PARAMETER stop <|begin▁of▁sentence|> PARAMETER stop <|end▁of▁sentence|> PARAMETER stop <|User|> PARAMETER stop <|Assistant|>

运行:

ollama create DeepSeek-R1-Distill-Qwen-1.5B -f /home/yyj/data/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B/Modelfile 3.1.4 检验Deepseek状态

检验ollama安装deepseek是否成功,命令如下:

curl :11434 3.1.5 ollama命令

常用命令如下:

# 列出可用的模型 ollama list # 加载并运行模型 ollama run <model_name> # 获取模型的信息 ollama info <model_name> # 列出所有已安装的模型 ollama installed # 安装特定的模型 ollama pull <model_name> # 卸载模型 ollama remove <model_name> # 显示帮助信息 ollama --help 3.2 vLLM方式 3.2.1 安装conda

官网地址:Download Anaconda Distribution | Anaconda (下载精简的Miniconda版本)

查看平台架构:

lscpu

根据平台架构下架(x86_64):

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

安装:

chmod +x Anaconda3-2024.10-1-Linux-x86_64.sh sh Anaconda3-2024.10-1-Linux-x86_64.sh

配置环境变量:

vim ~/.bashrc

参考内容:

export PATH="$PATH:{conda安装路径}/bin"

生效配置的环境变量:

source ~/.bashrc

查看版本:

conda -V # 初始化 Conda 运行环境 # 适用于 bash 终端用户(如 Ubuntu、CentOS、WSL 等) conda init bash # 适用于 zsh 终端用户(如 macOS 默认的终端 shell) conda init zsh

配置镜像加速:

# vim ~/.condarc vim /{conda安装目录}/.condarc

.condarc参考内容:

channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud

备用加速参考内容:

channels: - - - show_channel_urls: true default_channels: - - - custom_channels: conda-forge: msys2: bioconda: menpo: pytorch: pytorch-lts: simpleitk:

查看conda信息:

conda info

其他命令(有需求执行):

# 退出当前的 Conda 环境 conda deactivate # 退出 base 环境并不再自动激活 conda config --set auto_activate_base false 3.2.2 创建虚拟环境

You can create a new Python environment using conda:

# 创建conda虚拟环境 conda create -n vllm python=3.12 -y # 激活 conda activate vllm 3.2.3 安装pytorch

切换conda虚拟环境:

conda activate vllm

配置pip加速:

vim /etc/pip.conf

添加如下内容:

[global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple timeout = 600

测试生效:

pip config list

下载地址:download.pytorch.org/whl/torch/
根据显卡信息中的CUDA版本下载,因为显卡信息中的CUDA是CUDA Version: 12.8,这里需要下载低于12.8版本的。

下载: (cu124 指的是CUDA版本是12.4、cp312 指的是python 3.12环境),下载后保存到路径/usr/local下

安装:

# 安装 pip install /usr/local/torch-2.4.0+cu124-cp312-cp312-linux_x86_64.whl

验证安装:

pip show torch # 或者 pip list | grep torch 3.2.4 安装vllm

参考vllm官方文档:Installation — vLLM

命令:

# 切环境 conda activate vllm # 安装 pip install vllm

查看版本:

vllm --version

输出内容参考:

(vllm) [root@localhost bin]# vllm --version INFO 02-21 08:41:14 __init__.py:207] Automatically detected platform cuda. 0.7.3

升级vllm命令:

pip install --upgrade vllm 3.2.5 vllm运行deepseek

进入虚拟环境:

conda activate vllm

运行命令:

CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6 vllm serve /home/data/models/DeepSeek-R1-Distill-Qwen-32B \ --pipeline-parallel-size 7 \ --tensor-parallel-size 1 \ --host 0.0.0.0 \ --port 8000 \ --max_model_len 2048 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 32 \ --served-model-name "DeepSeek-R1-Distill-Qwen-32B" \ --dtype=half

参数的详细解释:

CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6
含义: 指定使用哪些 GPU 设备。这个环境变量告诉 CUDA 运行时只使用编号为 0 到 4 的 GPU(共 7 个 GPU)。
作用: 限制模型运行在指定的 GPU 上,而不是系统中的所有 GPU。
例子: 如果系统中还有其他 GPU(比如 7、8),它们不会被这个进程使用。

vllm serve
含义: 调用 vLLM 的服务启动命令,用于部署模型并提供推理服务。
作用: 启动一个服务器,允许通过网络请求(比如 HTTP API)对模型进行推理。

/home/data/models/DeepSeek-R1-Distill-Qwen-32B
含义: 指定要加载的模型路径。在 FP16 精度下(--dtype=half),每个参数占 2 字节,模型权重大约需要 64GB 显存。加上激活值、KV 缓存等,显存需求可能接近或超过 80GB。
作用: 告诉 vLLM 使用这个目录下的模型文件(DeepSeek-R1-Distill-Qwen-32B)进行推理。这通常是一个预训练的大型语言模型。

--pipeline-parallel-size 7
含义: 设置管道并行的大小为 7。
作用: 将模型的计算任务分成 7 个阶段,每个阶段分配给一个 GPU。这种方式利用多个 GPU 并行处理模型的不同层或部分,适合超大模型推理。
注意: 这里 7 对应于 CUDA_VISIBLE_DEVICES 中指定的 7 个 GPU。

--tensor-parallel-size 1
含义: 设置张量并行的大小为 1。
作用: 张量并行是将模型的张量(比如权重矩阵)分割到多个 GPU 上并行计算。这里设为 1,意味着不使用张量并行,每个 GPU 完整持有模型的一部分(配合管道并行使用)。
对比: 如果设为大于 1,会在多个 GPU 间分割同一层的计算。

--host 0.0.0.0
含义: 指定服务器监听的主机地址。
作用: 0.0.0.0 表示服务器监听所有网络接口,允许外部设备通过网络访问服务。
例子: 如果设为 127.0.0.1,则只能本地访问。

--port 8000
含义: 指定服务器监听的端口号。
作用: 服务将运行在 8000 端口,客户端可以通过这个端口发送推理请求。
例子: 你可以用 <服务器IP>:8000 来访问服务。

--max_model_len 2048
含义: 设置模型支持的最大序列长度为 2048 个 token。
作用: 限制输入和输出的总长度(包括上下文和生成内容),避免内存溢出。
注意: 如果输入超过这个长度,可能会被截断或报错。

--gpu-memory-utilization 0.9
含义: 设置 GPU 内存利用率为 90%。
作用: 控制每个 GPU 上分配给模型的显存比例(这里是 90%),剩余部分留给系统或其他开销。
例子: 如果一块 GPU 有 24GB 显存,这里会分配约 21.6GB 给模型。

--max-num-seqs 32

指定 vLLM 在一次批处理中最多处理的序列数(即最大 batch size)。它限制了并发请求的上限,直接影响吞吐量和显存使用。

vLLM 默认可能是 256(视版本而定),但会受显存和 --max_model_len 限制。

--served-model-name 'DeepSeek-R1-Distill-Qwen-32B'
含义: 指定服务中模型的名称。
作用: 客户端请求时可以用这个名字来标识模型,通常用于区分多个部署的模型。
例子: 在 API 请求中可能会用 "model": "DeepSeek-R1-Distill-Qwen-32B" 来调用。

--dtype=half
含义: 指定模型的数据类型为半精度浮点数(FP16)。
作用: 使用 FP16(而不是默认的 FP32)来减少显存占用并加速计算,同时保持合理的精度。
注意: 需要 GPU 支持 FP16 计算(比如 NVIDIA 的 Volta、Turing、Ampere 架构)。

其他说明

​ pipeline-parallel-size和tensor-parallel-size这两个参数相乘就是总的GPU需求数量,相乘的积需要小于总的可用的GPU数量,注意配置合理。

​ 实际生产过程中发现(7张T4):pipeline-parallel-size * tensor-parallel-size的积为偶数最佳,单独的一个显存用来分配给嵌入模型使用。

3.2.6 配置启动脚本

创建文件夹

mkdir -p /usr/local/deepseek 3.2.6.1 普通脚本

编辑脚本文件

vim /usr/local/deepseek/start_DeepSeek-R1-Distill-Qwen-32B_By_vLLM.sh

脚本内容参考如下:

#!/bin/bash # 加载 conda 环境 source /usr/local/miniconda3/etc/profile.d/conda.sh conda activate vllm # 启动 vllm 服务 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6 vllm serve /home/data/models/DeepSeek-R1-Distill-Qwen-32B \ --pipeline-parallel-size 7 \ --tensor-parallel-size 1 \ --host 0.0.0.0 \ --port 8000 \ --max_model_len 4096 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 32 \ --served-model-name 'DeepSeek-R1-Distill-Qwen-32B' \ --dtype=half

注意:如果需要显示Think标签,可以追加如下内容到start_DeepSeek-R1-Distill-Qwen-32B_By_vLLM.sh脚本中:

#!/bin/bash # 加载 conda 环境 source /usr/local/miniconda3/etc/profile.d/conda.sh conda activate vllm # 启动 vllm 服务 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6 vllm serve /home/data/models/DeepSeek-R1-Distill-Qwen-32B \ --pipeline-parallel-size 7 \ --tensor-parallel-size 1 \ --host 0.0.0.0 \ --port 8000 \ --max_model_len 4096 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 32 \ --served-model-name 'DeepSeek-R1-Distill-Qwen-32B' \ --dtype=half \ --chat-template /home/data/models/DeepSeek-R1-Distill-Qwen-32B/template_deepseek_r1.jinja

编辑systemd启动文件:

vim /etc/systemd/system/deepseek.service

内容参考如下:

[Unit] Description=DeepSeek-R1-Distill-Qwen-32B After=network.target [Service] Type=simple User=root WorkingDirectory=/usr/local/deepseek ExecStart=/bin/bash /usr/local/deepseek/start_DeepSeek-R1-Distill-Qwen-32B_By_vLLM.sh Restart=always [Install] WantedBy=multi-user.target

生效配置:

systemctl daemon-reload

启动、自启动:

systemctl start deepseek systemctl enable deepseek 3.2.6.2 高级脚本 #!/bin/bash # 脚本用途说明 echo "Starting vLLM server for DeepSeek-R1-Distill-Qwen-1.5B..." # 定义所有需要检查的路径和环境变量 CONDA_BASE="/usr/local/conda" # Miniconda 安装路径 CONDA_ENV="vllm" # Conda环境名称 MODEL_PATH="/home/yyj/data/models/DeepSeek-R1-Distill-Qwen-1.5B" # 模型路径 PORT=8000 # vLLM 服务端口 LOG_FILE="/usr/local/deepseek/vllm_server_for_deepseek_1.5B.log" #日志文件路径 # 设置错误处理:脚本在遇到错误时退出 set -e # 检查 Conda 路径是否存在 if [ ! -d "$CONDA_BASE" ]; then echo "Error: Miniconda not found at $CONDA_BASE. Please update CONDA_BASE in the script." exit 1 fi # 加载 Conda 环境 source "$CONDA_BASE/etc/profile.d/conda.sh" conda activate "$CONDA_ENV" || { echo "Error: Failed to activate conda environment '$CONDA_ENV'. Please ensure it exists." exit 1 } # 检查 NVIDIA GPU 是否可用 if ! command -v nvidia-smi &> /dev/null; then echo "Warning: nvidia-smi not found. GPU might not be available." else echo "GPU detected: $(nvidia-smi --query-gpu=name --format=csv,noheader)" fi # 检查模型路径是否存在 if [ ! -d "$MODEL_PATH" ]; then echo "Error: Model path $MODEL_PATH does not exist. Please update MODEL_PATH in the script." exit 1 fi # 启动 vLLM 服务 echo "Launching vLLM server on port $PORT..." CUDA_VISIBLE_DEVICES=0 vllm serve "$MODEL_PATH" \ --pipeline-parallel-size 1 \ --tensor-parallel-size 1 \ --host 0.0.0.0 \ --port "$PORT" \ --max_model_len 1024 \ --gpu-memory-utilization 0.85 \ --max-num-seqs 32 \ --served-model-name "DeepSeek-R1-Distill-Qwen-1.5B" \ 2>&1 | tee "$LOG_FILE" # 保存进程 ID 并等待几秒检查是否启动成功 VLLM_PID=$! sleep 5 if ps -p $VLLM_PID > /dev/null; then echo "vLLM server started successfully with PID $VLLM_PID. Logs are saved to $LOG_FILE." else echo "Error: vLLM server failed to start. Check $LOG_FILE for details." exit 1 fi echo "Server is running in the background. Access it at :$PORT."

编辑systemd启动文件:

[Unit] Description=DeepSeek-R1-Distill-Qwen-1.5B After=network.target [Service] Type=simple ExecStart=/usr/local/deepseek/start_DeepSeek-R1-Distill-Qwen-1.5B_By_vLLM.sh ExecStop=/bin/kill -TERM $MAINPID #Restart=on-failure #RestartSec=5s # 设置为脚本或模型所在的目录。 WorkingDirectory=/usr/local/deepseek #User= #Group=yyj StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target 3.2.7 优化 3.2.7.1 think思考标签

如果需要弃用think思考标签,需要添加--chat-template,修改启动脚本,内容参考如下:

#!/bin/bash # 加载 conda 环境 source /usr/local/miniconda3/etc/profile.d/conda.sh conda activate vllm # 启动 vllm 服务 CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6 vllm serve /home/data/models/DeepSeek-R1-Distill-Qwen-32B \ --pipeline-parallel-size 7 \ --tensor-parallel-size 1 \ --host 0.0.0.0 \ --port 8000 \ --max_model_len 4096 \ --gpu-memory-utilization 0.9 \ --max-num-seqs 32 \ --served-model-name 'DeepSeek-R1-Distill-Qwen-32B' \ --dtype=half \ --chat-template /home/data/models/DeepSeek-R1-Distill-Qwen-32B/template_deepseek_r1.jinja

template_deepseek_r1.jinja内容如下:

{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\\n' + '```json' + '\\n' + tool['function']['arguments'] + '\\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|>'}}{% endif %}

参考:本地部署DeepSeek-R1-Distill-Qwen-32B,输出仅有,没有 · Issue #352 · deepseek-ai/DeepSeek-R1

QwQ-32B Think标签优化

参考:Tutorial: How to Run QwQ-32B effectively | Unsloth Documentation

{%- if tools %} {{- '<|im_start|>system\n' }} {%- if messages[0]['role'] == 'system' %} {{- messages[0]['content'] }} {%- else %} {{- '' }} {%- endif %} {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }} {%- for tool in tools %} {{- "\n" }} {{- tool | tojson }} {%- endfor %} {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }} {%- else %} {%- if messages[0]['role'] == 'system' %} {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }} {%- endif %} {%- endif %} {%- for message in messages %} {%- if (message.role == "user") or (message.role == "system" and not loop.first) %} {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} {%- elif message.role == "assistant" and not message.tool_calls %} {%- set content = message.content.split('</think>')[-1].lstrip('\n') %} {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }} {%- elif message.role == "assistant" %} {%- set content = message.content.split('</think>')[-1].lstrip('\n') %} {{- '<|im_start|>' + message.role }} {%- if message.content %} {{- '\n' + content }} {%- endif %} {%- for tool_call in message.tool_calls %} {%- if tool_call.function is defined %} {%- set tool_call = tool_call.function %} {%- endif %} {{- '\n<tool_call>\n{"name": "' }} {{- tool_call.name }} {{- '", "arguments": ' }} {{- tool_call.arguments | tojson }} {{- '}\n</tool_call>' }} {%- endfor %} {{- '<|im_end|>\n' }} {%- elif message.role == "tool" %} {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} {{- '<|im_start|>user' }} {%- endif %} {{- '\n<tool_response>\n' }} {{- message.content }} {{- '\n</tool_response>' }} {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} {{- '<|im_end|>\n' }} {%- endif %} {%- endif %} {%- endfor %} {%- if add_generation_prompt %} {{- '<|im_start|>assistant\n' }} {%- endif %} 3.2.7.2 优化提示词

参考1:

先思考,然后按照以下格式回答用户的问题: <think>推理内容</think> 内容

参考2:

先从语义分析用户问题,若无法回答,再检索知识库;回答格式如下: <think>推理内容</think> 内容 3.2.8 调用测试

查看部署的模型:

curl :8000/v1/models

对话测试:

curl :8000/v1/completions \ -H "Content-Type: application/json" \ -d '{"model": "DeepSeek-R1-Distill-Llama-70B", "prompt": "1+1=", "max_tokens": 20}' 4.open-webui安装

采用docker方式安装:

docker run -d \ -p 3000:8080 \ --add-host=host.docker.internal:host-gateway \ -v /home/data/open-webui:/app/backend/data \ --restart always \ --name open-webui \ ghcr.nju.edu.cn/open-webui/open-webui:main

注意:将ghcr.io换成 ghcr.nju.edu.cn加速下载,使用教育网镜像加速超级快。

5.嵌入模型安装

参考地址:

5.1 本地方式安装

下载text-embeddings-inference源码,下载地址:Releases · huggingface/text-embeddings-inference · GitHub

解压:

unzip text-embeddings-inference-1.6.0.zip -C /usr/local/

进入源码目录:

cd /usr/local/text-embeddings-inference-1.6.0

卸载Rust:

rustup self uninstall

然后install Rust:

# 配置加速 # export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static # export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # 阿里云脚本 curl --proto '=https' --tlsv1.2 -sSf https://mirrors.aliyun.com/repo/rust/rustup-init.sh | sh

然后重新加载环境变量, 使 rustup 命令生效.

source $HOME/.cargo/env

查看Rust版本:

rustc --version

配置cargo加速:

vim ~/.cargo/config.toml

参考内容:

[source.crates-io] replace-with = 'tuna' [source.tuna] registry = "https://mirrors.tuna.tsinghua.edu.cn/git/crates.io-index.git"

指定rust版本:

vim /usr/local/text-embeddings-inference-1.6.0/rust-toolchain.toml

修改如下:

[toolchain] # 这里指定 1.85.0版本 channel = "1.85.0" components = ["rustfmt", "clippy"]

接着操作如下:

# 安装 cargo install --path router -F mkl # 这一步做好心里准备,网络不好可能也会弄个几个小时;如果网络有问题,试试命令:curl -I https://github.com,检查下github的网络可达性

安装文本处理工具:

text-embeddings-router --model-id /usr/local/{本地下载好的模型} --port 8080

可能会面临的问题:

5.2 Docker方式安装 5.2.1 安装容器依赖

安装docker容器的NVIDIA Container Toolkit的依赖,

参考:

​ Installing the NVIDIA Container Toolkit — NVIDIA Container Toolkit
​ 1. Introduction — Installation Guide for Linux 12.8 documentation
​ Ubuntu 22.04离线安装Docker和NVIDIA Container Toolkit - 知乎

如果以来下载慢/下载不下来,直接迅雷本地下载上传Linux后手动离线安装,我这里就离线安装了:
https://nvidia.github.io/libnvidia-container/stable/rpm/x86_64/nvidia-container-toolkit-base-1.17.4-1.x86_64.rpm

Github仓库地址:libnvidia-container/stable/rpm/x86_64 at gh-pages · NVIDIA/libnvidia-container

安装:

rpm -ivh nvidia-container-toolkit-base-1.17.5-1.x86_64.rpm

检验是否安装成功:

rpm -qa | grep nvidia-container-toolkit 5.2.2 下载模型

创建模型模型保存目录:

mkdir -p /usr/local/nomic-embed-text/model

去huggingface.co下载嵌入模型nomic-ai/nomic-embed-text-v1.5,然后保存到路径/usr/local/nomic-embed-text/model

5.2.2 安装嵌入模型

参考:GPTs-0071-部署 text-embeddings-inference:cpu-1.5 - 知乎

创建嵌入模型的基础目录:

mkdir -p /usr/local/embedding-model/

创建模型保存目录:

mkdir -p /usr/local/embedding-model/{你需要安装的嵌入模型的目录} # 示例 mkdir -p /usr/local/embedding-model/nomic-embed-text-v1.5

下载模型模型保存目录中,下载后的模型路径示例:/usr/local/embedding-model/nomic-embed-text-v1.5/nomic-embed-text-v1.5

注意:模型保存目录下需要保存模型的原有的目录(2个一样的目录才行),这个是需要挂载到容器内部的。

CPU部署参考命令如下:

docker run -itd \ -p 9003:80 \ -v /usr/local/embedding-model/nomic-embed-text-v1.5:/data \ --name nomic-embed-text-v1.5 \ --restart=always \ ghcr.nju.edu.cn/huggingface/text-embeddings-inference:cpu-1.6 \ --model-id /data/nomic-embed-text-v1.5

参数解释:

--model-id /data/nomic-embed-text-v1.5

这是传递给容器内应用程序的一个参数。

结合前面的 -v 挂载选项,这实际上是告诉容器使用宿主机上挂载到 /data 的模型文件(可能是 nomic-embed-text-v1.5 模型)。

注意:

可能面临的问题:

可能面临的报错:

Caused by: 0: request error: error sending request for url (https://huggingface.co/nomic-embed-text-v1.5/resolve/main/config.json): error trying to connect: tcp connect error: Connection timed out (os error 110) 1: error sending request for url (https://huggingface.co/nomic-embed-text-v1.5/resolve/main/config.json): error trying to connect: tcp connect error: Connection timed out (os error 110) 2: error trying to connect: tcp connect error: Connection timed out (os error 110) 3: tcp connect error: Connection timed out (os error 110) 4: Connection timed out (os error 110) # 如果你出现了上述报错,你一定是没仔细阅读本文档;需要采用离线方式下载模型后,保存到指定的目录下,请按照文档操作

GPU 部署参考命令如下:

docker run -itd \ --gpus '"device=4"' \ -p 9003:80 \ -v /home/embedding-models/bge-m3-model:/data \ --name bge-m3 \ --restart=always \ ghcr.nju.edu.cn/huggingface/text-embeddings-inference:89-1.6 \ --model-id /data/bge-m3 # /home/embedding-models/bge-m3-model路径下放了bge-m3下载下来的模型

其他:
在RAG中应用中,BGE-M3可以替代商业的embedding模型,实现低成本、可控的解决方案。它具备的两个重要的功能:

​ 多语言,可以支持100多种工作语言
​ 可输入最长8192个token的长文本。
​ 在进行生成应用时,我们除了关注模型本身的能力外,还需要关注其服务化的性能。

5.2.4 调用测试

BGE-M3调用测试命令:

curl -w "\n总时间: %{time_total}s\n名称解析时间: %{time_namelookup}s\n连接时间: %{time_connect}s\nTLS握手时间: %{time_appconnect}s\n等待时间: %{time_starttransfer}s\n数据传输时间: %{time_total}s\nHTTP状态码: %{http_code}\n" \ --location '10.0.10.251:9003/embeddings' \ --header 'Content-Type: application/json' \ --data '{ "input":["橘子洲,位于湖南省长沙市区中湘江江心,北纬28°10′23.40″、东经112°57′18.36″,是湘江下游众多冲积沙洲之一。橘子洲西望岳麓山,东临长沙城,四面环水,长达5千米,狭处横约40米,宽处横约140米,最宽处仅300余米,岛形狭长,形似长龙。橘子洲大桥从上横跨而过,离长沙市中心1千米。面积0.614平方千米。从自然演变过程来看,橘子洲为第四纪全新世时期形成的、典型的一级阶地地层,地貌属高河漫滩,主要由以下三方面因素作用而成:一是江心基岩凸起,湘江主流至此分流,分流携带的泥沙通过回流,淤落在江心突起之基岩上形成心滩;二是湘江长沙段江面变宽,江水流速减小,泥沙易于淤落;三是受下游浏阳河、捞刀河以及洞庭湖水顶托,泥沙易于淤落,天长地久,日积月累,“心滩”经新构造运动上升露出水面而形成一座江心岛。橘子洲上生长着数千种花草藤蔓植物,其中名贵植物有143种。有鹤、鹭、鸥、狐、獾等珍稀动物。2012年,长沙市岳麓山-橘子洲旅游区被评为国家AAAAA级景区,橘子洲是其重要组成部分。"], "model":"bge-m3" }'

这段curl会统计请求的各个阶段的耗时,将其在服务器上直接运行,避免网络带来的影响。如果需要对比CPU耗时,请部署CPU架构后测试,再对比数据。

bge-reranker-large调用测试命令:

curl -X 'POST' \ 'http://10.0.10.251:9004/rerank' \ -H 'accept: application/json' \ -H 'Content-Type: application/json' \ -d '{ "query": "What is Deep Learning?", "texts": [ "Deep Learning is ...", "hello"]}'

2025-11-27 16:28 点击量:1