Firefly ROC-RK3588S-PC大模型部署

[学习教程] Firefly ROC-RK3588S-PC大模型部署

适用硬件: Firefly ROC-RK3588S-PC (16GB RAM, 128GB eMMC)

核心目标: RKLLama 是一个专为瑞芯微 (Rockchip) NPU (RK3588/RK3576) 优化的推理服务器,兼容 Ollama 和 OpenAI API。

本文档将指导您如何准备环境、下载/转换模型(包括 .rkllm.rknn 格式),以及如何启动服务。

🚨 第一步:系统安装

1. 准备工作

  • Firefly ROC-RK3588S-PC 开发板 文档地址: 点击进入
  • USB Type-C数据线
  • 安装有Windows操作系统的电脑
  • Ubuntu22.04镜像文件 资料下载地址:点击进入
  • 刷写工具AndroidTool.exe

固件版本

2. 固件刷写

下载的固件包中已经包含刷写工具和驱动,如果没有可在官网下载
刷写固件工具和驱动

  • 驱动安装
    驱动安装

  • 接线、上电,插好电源线,使用microUSB线将开发板与电脑连接起来。

  • 进入提前下载并解压的AndroidTool文件夹,打开AndroidTool.exe

    打开AndroidTool

  • 连接好后设备下面会发现设备通常是发现adb设备(按下reset按钮会发现LOADER设备)

    打开AndroidTool

  • 直接点击升级固件,选择下载的固件(img),点击升级即可(升级前可先删除扇区数据)

    固件上传
    清空扇区数据

🔧 第二步:系统环境初始化

在部署之前,需要初始化环境比如系统安装包更新,检测NPU驱动,ip地址配置,docker安装等等

rk3588_init.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
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

#!/bin/bash

# =================================================================
# 脚本名称: ubuntu_init.sh
# 描述: Ubuntu 系统初始化工具 (系统信息、Root SSH、Docker 运维、系统更新、环境优化)
# 制作人: kikock
# =================================================================

# 检查是否以 root 权限运行
if [[ $EUID -ne 0 ]]; then
echo "错误: 请使用 sudo 或 root 用户运行此脚本。"
exit 1
fi

# 定义颜色常量
GREEN='\033[0;32m'
BLUE='\033[0;34m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # 重置颜色

# 1. 查看系统信息函数
show_sys_info() {
clear
echo -e "${BLUE}================ 系统详细信息 ================${NC}"

OS_NAME=$(lsb_release -ds 2>/dev/null || cat /etc/os-release | grep "PRETTY_NAME" | cut -d= -f2 | tr -d '"')
KERNEL=$(uname -r)
ARCH=$(uname -m)
CPU_MODEL=$(lscpu | grep "Model name" | cut -d: -f2 | xargs)

# 增强版内存抓取:兼容不同版本的 free 输出格式
# 移除冒号匹配以兼容中文环境的全角冒号 [cite: 5.1]
MEM_LINE=$(free -h | grep -E "Mem|内存")
# 如果关键字匹配失败,尝试直接读取第二行作为兜底
if [ -z "$MEM_LINE" ]; then
MEM_LINE=$(free -h | sed -n '2p')
fi

MEM_TOTAL=$(echo $MEM_LINE | awk '{print $2}')
MEM_USED=$(echo $MEM_LINE | awk '{print $3}')
MEM_FREE=$(echo $MEM_LINE | awk '{print $4}')

SWAP_LINE=$(free -h | grep -E "Swap|交换")
# 如果关键字匹配失败,尝试直接读取第三行作为兜底
if [ -z "$SWAP_LINE" ]; then
SWAP_LINE=$(free -h | sed -n '3p')
fi

SWAP_TOTAL=$(echo $SWAP_LINE | awk '{print $2}')
SWAP_USED=$(echo $SWAP_LINE | awk '{print $3}')


DISK_USAGE=$(df -h / | awk '/\// {print $5}')
IP_ADDR=$(hostname -I | cut -d' ' -f1)
UPTIME=$(uptime -p)

# 获取 NPU 实时频率 (针对 Kernel 6.1 路径)
if [ -f "/sys/class/devfreq/fdab0000.npu/cur_freq" ]; then
NPU_FREQ=$(cat /sys/class/devfreq/fdab0000.npu/cur_freq | awk '{printf "%.0f MHz\n", $1/1000000}')
else
NPU_FREQ="未激活/挂起"
fi

# 获取 NPU 驱动版本
if [ -f "/sys/kernel/debug/rknpu/version" ]; then
NPU_VER=$(cat /sys/kernel/debug/rknpu/version | grep -oE "v[0-9]+\.[0-9]+\.[0-9]+")
elif lsmod | grep -q "rknpu"; then
NPU_VER=$(modinfo rknpu 2>/dev/null | grep "^version:" | awk '{print $2}')
[ -z "$NPU_VER" ] && NPU_VER="已加载(版本未知)"
else
NPU_VER="未检测到驱动"
fi

# 获取系统温度
if [ -f "/sys/class/thermal/thermal_zone0/temp" ]; then
TEMP=$(cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000 "°C"}')
else
TEMP="未知"
fi


echo -e "${YELLOW}操作系统:${NC} $OS_NAME"
echo -e "${YELLOW}内核版本:${NC} $KERNEL"
echo -e "${YELLOW}系统架构:${NC} $ARCH"
echo -e "${YELLOW}处理器:${NC} ${CPU_MODEL:-未知}"
echo -e "${YELLOW}根分区占用:${NC} $DISK_USAGE"
echo -e "${YELLOW}物理内存:${NC} $MEM_TOTAL (已用: $MEM_USED / 空闲: $MEM_FREE)"
echo -e "${YELLOW}虚拟内存:${NC} $SWAP_TOTAL (已用: $SWAP_USED)"
echo -e "${YELLOW}NPU 频率:${NC} $NPU_FREQ"
echo -e "${YELLOW}NPU 驱动:${NC} $NPU_VER"
echo -e "${YELLOW}核心温度:${NC} $TEMP"
echo -e "${YELLOW}内网 IP:${NC} $IP_ADDR"
echo -e "${YELLOW}运行时间:${NC} $UPTIME"
echo -e "${BLUE}==============================================${NC}"
echo ""
read -p "按回车键返回主菜单..."
}

# 2. 修改 Root 密码并开启 SSH 登录
setup_root_ssh() {
echo -e "\n${BLUE}--- 开始配置 Root SSH 登录 ---${NC}"
echo -e "${YELLOW}请设置新的 Root 密码:${NC}"
passwd root

if [ $? -eq 0 ]; then
echo -e "${BLUE}正在修改 SSH 配置文件...${NC}"
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F_%T)
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
systemctl restart ssh

if [ $? -eq 0 ]; then
echo -e "${GREEN}成功: Root 密码已设置,且已允许 SSH 远程登录。${NC}"
else
echo -e "${RED}错误: SSH 服务重启失败。${NC}"
fi
else
echo -e "${RED}取消: 密码修改失败或用户取消操作。${NC}"
fi
echo ""
read -p "按回车键返回主菜单..."
}

# 3. 离线安装 Docker 逻辑 (已优化解压路径)
install_docker_offline() {
echo -e "\n${BLUE}--- 开始离线安装 Docker ---${NC}"

if command -v docker &> /dev/null; then
echo -e "${YELLOW}检测到系统已安装 Docker,脚本将进行覆盖升级/重置操作。${NC}"
fi

read -p "请输入 Docker 离线包名称 (如 docker-26.1.3.tgz): " TAR_NAME
TAR_FILE="./docker/$TAR_NAME"
TEMP_DIR="./dockerApp"

if [ ! -f "$TAR_FILE" ]; then
echo -e "${RED}错误: 在 ./docker/ 目录下找不到文件 $TAR_NAME${NC}"
return
fi

# 环境准备
echo -e "${YELLOW}正在处理 SELinux ...${NC}"
if [ -f /etc/selinux/config ]; then
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
setenforce 0 2>/dev/null
fi

# 创建隔离的解压目录
[ -d "$TEMP_DIR" ] && rm -rf "$TEMP_DIR"
mkdir -p "$TEMP_DIR"

echo -e "${YELLOW}正在解压 $TAR_NAME 到 $TEMP_DIR ...${NC}"
tar -xzvf "$TAR_FILE" -C "$TEMP_DIR"
if [ $? -ne 0 ]; then
echo -e "${RED}错误: 解压失败。${NC}"
rm -rf "$TEMP_DIR"
return
fi

# 配置目录与文件分发 (从临时目录拷贝)
echo -e "${YELLOW}分发二进制文件与配置...${NC}"
[ ! -d "/etc/docker" ] && mkdir -p "/etc/docker"

# 拷贝解压后的 etc 目录内容
if [ -d "$TEMP_DIR/etc" ]; then
cp -r "$TEMP_DIR/etc/"* /etc/
fi

# 拷贝解压后的 docker 二进制文件
if [ -d "$TEMP_DIR/docker" ]; then
cp "$TEMP_DIR/docker/"* /usr/bin/
fi

# 核心组件来源: ./docker/ (用户指定的下级目录)
if [ -f "./docker/docker.service" ]; then
cp ./docker/docker.service /usr/lib/systemd/system/
chmod +x /usr/lib/systemd/system/docker.service
else
echo -e "${RED}警告: 在 ./docker/ 目录下未发现 docker.service 文件。${NC}"
fi

echo -e "${YELLOW}正在加载配置并启动/重启 Docker 服务...${NC}"
systemctl daemon-reload
# 使用 restart 确保如果是覆盖安装能立即生效
systemctl restart docker
systemctl enable docker.service

# 安装 docker-compose (来源: ./docker/)
if [ -f "./docker/docker-compose" ]; then
echo -e "${YELLOW}配置 docker-compose...${NC}"
cp ./docker/docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose
ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
fi

# 清理临时解压目录
echo -e "${YELLOW}清理临时文件...${NC}"
rm -rf "$TEMP_DIR"

echo -e "${GREEN}Docker 离线安装/更新任务执行完毕。${NC}"
docker -v
}

# 4. 卸载 Docker 逻辑
uninstall_docker() {
echo -e "\n${RED}--- 开始卸载 Docker ---${NC}"
read -p "确定要彻底卸载 Docker 及其组件吗? (y/n): " confirm
[[ "$confirm" != "y" ]] && return

systemctl stop docker 2>/dev/null
systemctl disable docker 2>/dev/null
rm -f /usr/bin/docker* /usr/bin/containerd* /usr/bin/runc /usr/bin/ctr
rm -f /usr/local/bin/docker-compose /usr/bin/docker-compose
rm -f /usr/lib/systemd/system/docker.service
rm -rf /etc/docker
systemctl daemon-reload
echo -e "${GREEN}Docker 卸载完成。${NC}"
}

# 5. 常用 Docker 命令说明
show_docker_commands() {
clear
echo -e "${BLUE}================ 常用 Docker 命令参考 ================${NC}"
echo -e "${YELLOW}[ 容器管理 ]${NC}"
echo " docker ps - 查看运行中的容器"
echo " docker ps -a - 查看所有容器 (包括已停止)"
echo " docker start [ID] - 启动容器"
echo " docker stop [ID] - 停止容器"
echo " docker restart [ID]- 重启容器"
echo " docker logs -f [ID]- 查看容器实时日志"
echo " docker exec -it [ID] /bin/bash - 进入容器终端"
echo ""
echo -e "${YELLOW}[ 镜像管理 ]${NC}"
echo " docker images - 列出本地所有镜像"
echo " docker rmi [ID] - 删除本地镜像"
echo " docker pull [NAME] - 从仓库拉取镜像"
echo ""
echo -e "${YELLOW}[ Docker Compose ]${NC}"
echo " docker-compose up -d - 后台启动所有服务"
echo " docker-compose down - 停止并移除所有服务"
echo " docker-compose ps - 查看服务状态"
echo -e "${BLUE}======================================================${NC}"
echo ""
read -p "按回车键返回..."
}

# 6. 安装 Docker Web 管理功能 (docker-fast)
install_docker_fast_web() {
echo -e "\n${BLUE}--- 开始安装 Docker Web 管理终端 ---${NC}"

# 检查 Docker 是否安装
if ! command -v docker &> /dev/null; then
echo -e "${RED}错误: 未检测到 Docker,请先安装 Docker。${NC}"
return
fi

# 检查 docker-fast.yml 是否存在
YML_FILE="./docker/docker-fast.yml"
if [ ! -f "$YML_FILE" ]; then
echo -e "${RED}错误: 在 ./docker/ 目录下找不到 docker-fast.yml 文件。${NC}"
return
fi

# 检查是否已经运行
if docker ps --format '{{.Names}}' | grep -q "docker-fast"; then
echo -e "${YELLOW}检测到 Docker-Fast 已在运行,将进行配置检查并尝试更新。${NC}"
fi

echo -e "${YELLOW}正在使用 docker-compose 部署/更新 Web 管理端...${NC}"

# 优先尝试 docker-compose 命令,其次尝试 docker compose
if command -v docker-compose &> /dev/null; then
docker-compose -f "$YML_FILE" up -d
elif docker compose version &> /dev/null; then
docker compose -f "$YML_FILE" up -d
else
echo -e "${RED}错误: 未检测到 docker-compose,请检查安装情况。${NC}"
return
fi

if [ $? -eq 0 ]; then
echo -e "${GREEN}成功: Docker Web 管理端已启动/更新。${NC}"
echo -e "${BLUE}提示: 请检查 $YML_FILE 中的端口映射,并使用浏览器访问服务器 IP。${NC}"
else
echo -e "${RED}错误: 部署失败。${NC}"
fi
}

# 7. Docker 管理二级菜单
docker_menu() {
while true; do
clear
echo -e "${GREEN}==============================================${NC}"
echo -e "${GREEN} Docker 管理 (二级菜单) ${NC}"
echo -e "${GREEN}==============================================${NC}"
echo " 1. 离线安装 Docker"
echo " 2. 彻底卸载 Docker"
echo " 3. 常用 Docker 命令说明"
echo " 4. 安装 Docker Web 管理终端 (docker-fast)"
echo " 0. 返回主菜单"
echo -e "${GREEN}==============================================${NC}"
read -p "请选择操作 [0-4]: " sub_choice

case $sub_choice in
1) install_docker_offline; read -p "按回车键继续..." ;;
2) uninstall_docker; read -p "按回车键继续..." ;;
3) show_docker_commands ;;
4) install_docker_fast_web; read -p "按回车键继续..." ;;
0) break ;;
*) echo -e "${RED}无效输入。${NC}"; sleep 1 ;;
esac
done
}

# 8. 系统软件包更新函数
update_system_packages() {
echo -e "\n${BLUE}--- 开始更新系统软件包 ---${NC}"
echo -e "${YELLOW}1. 正在更新软件源 (apt update)...${NC}"
apt update
if [ $? -eq 0 ]; then
echo -e "${YELLOW}2. 正在升级软件包 (apt upgrade)...${NC}"
apt upgrade -y
if [ $? -eq 0 ]; then
echo -e "${GREEN}成功: 系统软件包已全部更新完毕。${NC}"
else
echo -e "${RED}错误: 软件包升级过程中出现问题。${NC}"
fi
else
echo -e "${RED}错误: 无法更新软件源,请检查网络。${NC}"
fi
echo ""
read -p "按回车键返回主菜单..."
}

system_optimization_menu() {
# 定义颜色常量 (如果外部未定义)
local GREEN='\033[0;32m'
local YELLOW='\033[1;33m'
local RED='\033[0;31m'
local BLUE='\033[0;34m'
local NC='\033[0m'

# Root 权限检查
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}错误: 必须以 root 权限运行此脚本。${NC}"
return 1
fi

while true; do
clear
echo -e "${GREEN}==============================================${NC}"
echo -e "${GREEN} 系统环境优化 (二级菜单) ${NC}"
echo -e "${GREEN}==============================================${NC}"
echo -e " 1. 切换至阿里云镜像源 (Ubuntu 专用)"
echo -e " 2. 开启内核 BBR 网络加速"
echo -e " 3. 配置 2GB zRAM 虚拟内存 (高压缩比)"
echo -e " 4. 清除 zRAM/Swap 所有相关配置"
echo -e " 5. 设置系统时区为上海 (Asia/Shanghai)"
echo -e " 0. 返回主菜单"
echo -e "${GREEN}==============================================${NC}"
read -p "请选择操作 [0-5]: " opt_choice

case $opt_choice in
1)
echo -e "${YELLOW}正在备份并尝试切换镜像源...${NC}"
cp /etc/apt/sources.list /etc/apt/sources.list.bak 2>/dev/null
# 兼容旧版 sources.list 和新版 sources.list.d 结构 (Ubuntu 24.04+)
sed -i 's|http://.*.ubuntu.com|http://mirrors.aliyun.com|g' /etc/apt/sources.list
apt update
echo -e "${GREEN}成功: 镜像源处理完成。${NC}"
read -p "按回车键继续..."
;;
2)
echo -e "${YELLOW}正在配置 BBR 加速...${NC}"
if ! grep -q "net.core.default_qdisc=fq" /etc/sysctl.conf; then
echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf
echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf
sysctl -p
echo -e "${GREEN}成功: BBR 已开启。${NC}"
else
echo -e "${BLUE}提示: BBR 似乎已经开启,无需重复操作。${NC}"
fi
read -p "按回车键继续..."
;;
3)
echo -e "${YELLOW}正在部署 zRAM 2GB 持久化方案...${NC}"
if swapon --show | grep -q "/dev/zram0"; then
echo -e "${BLUE}提示: zRAM 已经在运行中。${NC}"
else
# 创建初始化脚本
cat > /usr/local/bin/zram-init.sh <<EOF
#!/bin/bash
/sbin/modprobe zram num_devices=1
echo lzo > /sys/block/zram0/comp_algorithm
echo 2147483648 > /sys/block/zram0/disksize
/sbin/mkswap /dev/zram0
/sbin/swapon /dev/zram0 -p 10
EOF
chmod +x /usr/local/bin/zram-init.sh

# 创建 Systemd 服务
cat > /etc/systemd/system/zram-setup.service <<EOF
[Unit]
Description=Setup zRAM Swap
After=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/zram-init.sh

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now zram-setup.service
echo -e "${GREEN}成功: 2GB zRAM 已开启并设置为开机自启。${NC}"
fi
sleep 2
;;
4)
echo -e "${YELLOW}正在彻底移除虚拟内存配置...${NC}"
systemctl stop zram-setup.service 2>/dev/null
systemctl disable zram-setup.service 2>/dev/null
rm -f /etc/systemd/system/zram-setup.service
rm -f /usr/local/bin/zram-init.sh
swapoff /dev/zram0 2>/dev/null
modprobe -r zram 2>/dev/null
systemctl daemon-reload
echo -e "${GREEN}成功: 配置已清除。${NC}"
sleep 2
;;
5)
echo -e "${YELLOW}正在更新系统时区...${NC}"
timedatectl set-timezone Asia/Shanghai
echo -e "${GREEN}成功: 当前系统时间: $(date)${NC}"
read -p "按回车键继续..."
;;
0)
echo -e "${BLUE}返回中...${NC}"
break
;;
*)
echo -e "${RED}输入有误,请输入 0-5 之间的数字。${NC}"
sleep 1
;;
esac
done
}

# 主菜单循环
while true; do
clear
echo -e "${GREEN}==============================================${NC}"
echo -e "${GREEN} Ubuntu 系统初始化工具箱 - By kikock ${NC}"
echo -e "${GREEN}==============================================${NC}"
echo " 1. 查看系统详细信息 (包含架构)"
echo " 2. 修改 Root 密码并开启 SSH 登录"
echo " 3. Docker 管理 (安装/卸载/命令/Web)"
echo " 4. 系统软件包更新 (apt update & upgrade)"
echo " 5. 系统环境优化 (源/BBR/Swap/时区)"
echo " 0. 退出脚本"
echo -e "${GREEN}==============================================${NC}"
read -p "请输入选项 [0-5]: " choice

case $choice in
1) show_sys_info ;;
2) setup_root_ssh ;;
3) docker_menu ;;
4) update_system_packages ;;
5) system_optimization_menu ;;
0) echo -e "${BLUE}感谢使用,再见!- kikock${NC}"; exit 0 ;;
*) echo -e "${RED}输入无效,请重新选择。${NC}" ; sleep 1 ;;
esac
done


ps: docker 安装需要在当前文件夹下创建docker文件加内部结构如下:

~/docker /
├── docker-26.1.3.tgz # docker 安装包(arm架构)
├── docker-compose # docker-compose
├── docker-fast.yml # docker web管理容器
└── docker.service/ # docker服务文件

初始脚本可查看系统信息如下:

系统信息

cat /sys/kernel/debug/rknpu/version

  • 要求: 驱动版本建议 >= 0.9.6。如果版本过低,建议升级开发板固件。

2. 部署配置 (Docker Compose)

我们推荐使用 Docker Compose 进行管理,这样可以固化启动参数,避免每次输入长命令。

2.1 创建目录结构

在您的宿主机上创建一个文件夹(例如 ~/rkllama_docker),结构如下:

~/rkllama_docker/
├── docker-compose.yml # 服务配置文件
├── deploy.sh # 一键启动脚本
└── models/ # [自动创建] 存放模型文件的目录

2.2 配置文件 docker-compose.yml

请将以下内容保存为 docker-compose.yml:

version: ‘3.8’

services:
rkllama:
image: ghcr.io/notpunchnox/rkllama:main
container_name: rkllama
restart: unless-stopped

\# \[关键\] 必须开启特权模式,否则容器无法访问 NPU 和 DMA Buffer
privileged: true

\# 端口映射:API 服务端口 (兼容 Ollama API)
ports:
  \- "8080:8080"

\# 目录挂载:
\# 左边 ./models 是宿主机路径 (您存放 .rkllm 文件的地方)
\# 右边 /opt/rkllama/models 是容器内固定路径 (不可修改)
volumes:
  \- ./models:/opt/rkllama/models

\# 环境变量配置
environment:
  \# RKNPU\_VERBOSE=1 可开启 NPU 底层日志,生产环境可注释掉
  \- RKNPU\_VERBOSE=1
  \- TZ=Asia/Shanghai

\# 设备节点映射 (开启 privileged 后可选,但显式声明更清晰)
devices:
  \- /dev/dri:/dev/dri
  \- /dev/rga:/dev/rga
  \- /dev/dma\_heap:/dev/dma\_heap

\# 健康检查
healthcheck:
  test: \["CMD", "curl", "-f", "http://localhost:8080/api/version"\]
  interval: 30s
  timeout: 10s
  retries: 3

3. 快速启动

您可以直接运行 docker compose up -d,或者使用下面的脚本来确保目录权限正确。

3.1 一键启动脚本 deploy.sh

#!/bin/bash

# 1. 自动创建模型目录
if [ ! -d “./models” ]; then
echo “📂 正在创建本地模型目录: ./models”
mkdir -p ./models
fi

# 2. 启动服务
echo “🚀 正在启动 rkllama…”
docker compose up -d || docker-compose up -d

# 3. 实时查看日志
echo “📋 服务已启动,正在查看日志 (按 Ctrl+C 退出)…”
sleep 2
docker logs -f rkllama

给脚本执行权限并运行:

chmod +x deploy.sh
./deploy.sh

4. 添加与加载模型

RKLLama 容器启动后,它会自动监视挂载的 ./models 目录。

4.1 手动添加模型 (离线模式)

  1. 创建模型子目录:
    在 ./models 下为每个模型创建一个文件夹。
    mkdir -p models/my-qwen-model

  2. 放入文件:
    将下载好的 .rkllm 文件和分词器配置文件(tokenizer.json 等)放入该文件夹。

    • 如果没有分词器文件,必须确保开发板能联网。
  3. 创建 Modelfile:
    在文件夹内创建 Modelfile 文件:
    FROM=”your-model.rkllm”
    # 联网下载 Tokenizer 配置:
    HUGGINGFACE_PATH=”Qwen/Qwen2.5-3B-Instruct”
    # 或者使用本地 Tokenizer:
    # TOKENIZER=”.”

  4. 加载模型:
    # 在宿主机执行,让容器内的客户端加载模型
    docker exec -it rkllama rkllama load my-qwen-model

4.2 自动下载模型 (在线模式)

进入容器使用交互式命令下载:

docker exec -it rkllama rkllama pull

根据提示输入 HuggingFace 的 Repo ID 和文件名即可。

5. 验证与监控

5.1 验证 NPU 是否工作

在宿主机上使用监控命令:

sudo watch -n 1 “cat /sys/kernel/debug/rknpu/load”

当您与模型对话时,如果 NPU 负载跳动(> 0%),说明 Docker 穿透成功。

5.2 测试 API

默认 API 地址为 http://localhost:8080。

curl -X POST http://localhost:8080/api/chat \
-H “Content-Type: application/json” \
-d ‘{
“model”: “my-qwen-model”,
“messages”: [{“role”: “user”, “content”: “你好”}],
“stream”: false
}’

6. 常见问题

  • Error: Model directory not found:
    • 原因:宿主机的 ./models 目录下没有对应的子文件夹。
    • 解决:确保模型文件放在 ./models/<模型名>/ 里面,而不是直接放在根目录。
  • NPU 占用率为 0%:
    • 原因:Docker 容器没有权限。
    • 解决:确保 docker-compose.yml 中包含 privileged: true。
  • Tokenizer not found:
    • 原因:缺少分词器配置文件且无法联网。
    • 解决:手动下载以下文件放入模型目录,并在 Modelfile 中指定 TOKENIZER=”.”。
      • tokenizer.json (核心文件)
      • tokenizer_config.json (配置参数)
      • special_tokens_map.json (特殊字符映射)
      • config.json (可选,部分模型需要)

7. 常用模型管理命令

在宿主机上,您可以通过 docker exec 执行以下命令来管理容器内的模型:

功能 命令 说明
查看列表 docker exec -it rkllama rkllama list 列出所有已安装的模型
运行对话 docker exec -it rkllama rkllama run <模型名> 启动交互式命令行对话
加载模型 docker exec -it rkllama rkllama load <模型名> 仅将模型加载到 NPU 内存 (不进入对话)
卸载模型 docker exec -it rkllama rkllama unload 卸载当前运行的模型,释放 NPU 内存
查看详情 docker exec -it rkllama rkllama info <模型名> 查看模型的元数据信息
删除模型 docker exec -it rkllama rkllama rm <模型名> 删除指定模型文件
下载模型 docker exec -it rkllama rkllama pull 交互式从 Hugging Face 拉取模型