1. 引言:为什么选择离线部署
在当今AI技术快速发展的时代,许多企业面临着数据安全与合规性的严格要求,特别是在金融、医疗和政府等领域,离线部署AI模型成为刚需。本文将详细介绍如何利用Xinference框架在完全离线的环境中部署四种核心AI能力:文本嵌入(Embedding)、重排序(Reranker)、语音识别(STT)和语音合成(TTS)。
2. 方案概述
离线部署方案具有以下特点:
-
全流程离线:服务部署完全脱离互联网;
-
一键式部署:通过脚本自动化完成复杂配置;
-
资源可控:精确分配GPU资源,避免冲突;
-
模型灵活管理:支持按需插拔不同模型。
3. 准备工作
3.1 资源下载(联网机器)
首先需要在可联网的机器上准备所需资源:
|
1
2
3
4
5
6
7
8
9
10
11
|
拉取Xinference官方镜像
docker pull xprobe/xinference:latest
# 保存为离线包
docker save xprobe/xinference:latest -o xinference-image.tar
# 下载所需模型(登录魔塔,根据需求搜索模型,搜索后点击目标模型,右侧下载模型)
modelscope download --model maidalun/bce-embedding-base_v1
modelscope download --model maidalun/bce-reranker-base_v1
modelscope download --model iic/CosyVoice-300M
modelscope download --model iic/SenseVoiceSmall
|
模型会默认下载到/root/.cache/modelscope/hub/models/路径下:
|
1
2
3
4
|
├── iic/CosyVoice-300M
├── iic/SenseVoiceSmall
├── maidalun/bce-embedding-base_v1
└── maidalun/bce-reranker-base_v1
|
3.2 离线包目录结构规划
|
1
2
3
4
5
6
7
8
9
10
11
|
model_services/
├── docker/
│ ├── images/xinference-image.tar
│ └── docker-compose.yaml
├── models/
│ ├── bce-embedding-base_v1
│ ├── bce-reranker-base_v1
│ ├── CosyVoice-300M
│ └── SenseVoiceSmall
├── config.ini
└── install.sh
|
3.2.1. 配置文件(config.ini)
|
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
|
[XINFERENCE]
# 指定Xinference服务可用的GPU设备ID(逗号分隔多个ID,如"0,1")
# 注意:实际GPU编号需与服务器物理设备一致,可通过`nvidia-smi -L`查看
XINFERENCE_GPUS="0,1"
# 模型挂载路径
MODELS_VOLUMES_DIRECTORY=/data/docker_models
[EMBEDDING]
# 是否启用嵌入模型自动安装(true/true)
EMBEDDING_INSTALL_ENABLE=true
# 嵌入模型运行时绑定的GPU设备编号
# 必须存在于XINFERENCE_GPUS定义的可用设备列表中
# 示例:若XINFERENCE_GPUS="1",则此处只能填1
EMBEDDING_GPU=0
[RERANKER]
# 是否启用重排序模型自动安装(true/true)
RERANKER_INSTALL_ENABLE=true
# 重排序模型绑定的GPU设备编号
# 需与XINFERENCE_GPUS定义的设备一致
RERANKER_GPU=0
[TTS]
# 是否启用语音合成(TTS)模型安装(true/true)
TTS_INSTALL_ENABLE=true
# TTS模型绑定的GPU设备编号
# 若与嵌入模型共用GPU,需确保总显存不超限
TTS_GPU=0
[STT]
# 是否启用语音识别(STT)模型安装(true/true)
STT_INSTALL_ENABLE=true
# STT模型绑定的GPU设备编号
# 语音识别通常需要更多显存,建议独占GPU
STT_GPU=1
|
关键配置说明:
-
GPU分配策略:语音识别模型通常需要更多显存,建议独占GPU
-
模型路径:确保容器内外的路径映射正确
-
启用标志:可灵活控制哪些模型需要加载
3.2.2. Docker编排文件(docker-compose.yaml)
|
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.3"
services:
xinference:
image: xprobe/xinference:latest
container_name: xinference
restart: unless-stopped
command: ["xinference-local", "-H", "0.0.0.0"] # 启动命令
ports:
- "9997:9997" # 默认API端口
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9997"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
environment:
- XINFERENCE_GPUS=${XINFERENCE_GPUS:-"0"} # 从环境变量读取GPU ID,默认使用GPU 0
volumes:
- ${MODELS_VOLUMES_DIRECTORY}:/root/.xinference/models # 模型数据持久化
deploy:
resources:
reservations:
devices:
- driver: nvidia
capabilities: [gpu]
device_ids: ["0,1"]
|
3.2.3. 自动化部署脚本
|
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#! /bin/bash
#-----------------------------------------------------------
# 模型安装配置脚本
# 1.加载config.ini配置文件
# 2.拷贝模型文件到模型挂载路径
# 3.解压xinference镜像并运行xinference容器
# 4.加载模型
# 5.查看模型状态
#-----------------------------------------------------------
# 加载config.ini配置文件
while
IFS=
'='
read
-r key value || [[ -n
"$key"
]];
do
# 修剪 key 和 value 的首尾空格和换行符
key=$(
echo
"$key"
|
tr
-d
'\r\n'
|
xargs
)
value=$(
echo
"$value"
|
tr
-d
'\r\n'
|
xargs
)
# 跳过空行、注释行(以#开头)或段标记(如[section])
if
[[
"$key"
=
""
||
"$key"
=~ ^
# || "$key" =~ ^\[.*\] ]]; then
continue
fi
export
"$key=$value"
done
< config.ini
# 创建并验证目标目录
if
[ ! -d
"${MODELS_VOLUMES_DIRECTORY}"
];
then
echo
"创建模型目录: ${MODELS_VOLUMES_DIRECTORY}"
mkdir
-p
"${MODELS_VOLUMES_DIRECTORY}"
|| {
echo
"错误:无法创建目录 ${MODELS_VOLUMES_DIRECTORY}"
exit
1
}
fi
# 拷贝模型文件到模型挂载路径
#cp -r models/* ${MODELS_VOLUMES_DIRECTORY}
# 解压xinference容器镜像
#docker load < docker/images/xinference-image.tar
# 运行xinference容器
docker-compose -f .
/docker/docker-compose
.yaml up -d
while
true
;
do
status=$(docker inspect --
format
=
'{{.State.Health.Status}}'
xinference)
if
[
"$status"
=
"healthy"
];
then
break
fi
echo
"等待Xinference健康状态... 当前状态: $status"
sleep
10
done
echo
"加载模型"
# 函数:检查模型是否已注册
function
is_model_registered() {
local
model_name=
"$1"
docker
exec
xinference xinference list |
grep
-q
"$model_name"
}
if
[[
"${EMBEDDING_INSTALL_ENABLE}"
=
"true"
]] ;
then
MODEL_NAME=
"bce-embedding-base_v1"
MODEL_TYPE=
"embedding"
if
! is_model_registered
"$MODEL_NAME"
;
then
echo
"启动嵌入模型: ${MODEL_NAME}"
docker
exec
xinference xinference launch \
--model-name
"$MODEL_NAME"
\
--model-
type
"$MODEL_TYPE"
\
--model-path
"/root/.xinference/models/${MODEL_NAME}"
\
--gpu-idx
"$EMBEDDING_GPU"
fi
fi
if
[[
"${RERANKER_INSTALL_ENABLE}"
=
"true"
]] ;
then
MODEL_NAME=
"bce-reranker-base_v1"
MODEL_TYPE=
"rerank"
if
! is_model_registered
"$MODEL_NAME"
;
then
echo
"加载重排序模型: ${MODEL_NAME}"
docker
exec
xinference xinference launch \
--model-name
"$MODEL_NAME"
\
--model-
type
"$MODEL_TYPE"
\
--model-path
"/root/.xinference/models/${MODEL_NAME}"
\
--gpu-idx
"$RERANKER_GPU"
fi
fi
if
[[
"${TTS_INSTALL_ENABLE}"
=
"true"
]] ;
then
MODEL_NAME=
"CosyVoice-300M"
MODEL_TYPE=
"audio"
if
! is_model_registered
"$MODEL_NAME"
;
then
echo
"加载TTS模型: ${MODEL_NAME}"
docker
exec
xinference xinference launch \
--model-name
"$MODEL_NAME"
\
--model-
type
"$MODEL_TYPE"
\
--model-path
"/root/.xinference/models/${MODEL_NAME}"
\
--gpu-idx
"$TTS_GPU"
fi
fi
if
[[
"${STT_INSTALL_ENABLE}"
=
"true"
]];
then
MODEL_NAME=
"SenseVoiceSmall"
MODEL_TYPE=
"audio"
if
! is_model_registered
"$MODEL_NAME"
;
then
echo
"加载STT模型: ${MODEL_NAME}"
docker
exec
xinference xinference launch \
--model-name
"$MODEL_NAME"
\
--model-
type
"$MODEL_TYPE"
\
--model-path
"/root/.xinference/models/${MODEL_NAME}"
\
--gpu-idx
"$STT_GPU"
fi
fi
echo
"查看模型状态"
docker
exec
xinference xinference list
echo
"完成模型注册"
|
3.2.4 压缩离线包
|
1
|
tar
-czvf model_services.
tar
.gz model_services
|
4. 离线服务器部署步骤
4.1 前提条件
确保服务器已安装配置好docker、docker-compose并配置好nvidia-container-runtime。
4.2 传输资源包
|
1
|
scp
model_services.
tar
.gz user@offline-server:
/data/
|
4.3 解压资源
|
1
|
tar
-xzvf model_services.
tar
.gz -C
/data/
|
4.4 修改配置
根据实际服务器GPU情况调整config.ini中的设备分配。
注意: xinference上加载的模型并不支持配置显存。
执行部署:
|
1
2
3
|
cd
/data/model_services
chmod
+x
install
.sh
.
/install
.sh
|
脚本执行日志:
|
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
38
39
|
[+] Running 1
/1
✔ Container xinference Running 0.0s
加载模型
UID Type Name
------------------------ ------ ---------------
SenseVoiceSmall-Z61fh3ys audio SenseVoiceSmall
启动嵌入模型: bce-embedding-base_v1
Launch model name: bce-embedding-base_v1 with kwargs: {}
Launching model: 100%|██████████ | 100.0%
Model uid: bce-embedding-base_v1
UID Type Name Dimensions
--------------------- --------- --------------------- ------------
bce-embedding-base_v1 embedding bce-embedding-base_v1 768
UID Type Name
------------------------ ------ ---------------
SenseVoiceSmall-Z61fh3ys audio SenseVoiceSmall
加载重排序模型: bce-reranker-base_v1
Launch model name: bce-reranker-base_v1 with kwargs: {}
Launching model: 100%|██████████ | 100.0%
........
加载TTS模型: CosyVoice-300M
Launch model name: CosyVoice-300M with kwargs: {}
Launching model: 100%|██████████ | 100.0%
Launching model: 100%|██████████ | 100.0%
Model uid: CosyVoice-300M
.......
查看模型状态
UID Type Name Dimensions
--------------------- --------- --------------------- ------------
bce-embedding-base_v1 embedding bce-embedding-base_v1 768
UID Type Name
-------------------- ------ --------------------
bce-reranker-base_v1 rerank bce-reranker-base_v1
UID Type Name
------------------------ ------ ---------------
SenseVoiceSmall audio SenseVoiceSmall
CosyVoice-300M audio CosyVoice-300M
完成模型注册
|
5. 服务验证与测试
5.1 基础检查
|
1
2
3
4
5
|
# 检查容器状态
docker
ps
|
grep
xinference
# 查看模型列表
docker
exec
xinference xinference list
|
5.2 API接口测试
文本嵌入测试:
|
1
2
3
|
curl -X POST
"http://localhost:9997/v1/embeddings"
\
-H
"Content-Type: application/json"
\
-d
'{"model": "bce-embedding-base_v1", "input": "测试文本"}'
|
5.3 xinference图形化界面测试

点击语音识别模型行Actions按钮,测试语音识别:

6、总结
通过本文介绍的方案,企业可以在完全离线的环境中快速部署一套功能完整的AI能力平台。该方案不仅保证了数据的安全性,还通过灵活的配置满足了不同场景的需求。Xinference框架的轻量级特性使其成为离线部署的理想选择,而我们的自动化脚本则大大降低了部署复杂度。
未来,随着模型技术的进步,我们可以通过同样的方式无缝升级模型版本,持续提升业务系统的AI能力,而无需改变整体架构。
原创作者: zhangmingcheng 转载于: https://www.cnblogs.com/zhangmingcheng/p/18989096


所有评论(0)