HLIECpp / HLIELLama / HLIEvLLM / HLIEPython 部署与使用说明
| 版本 | 日期 | 描述 |
|---|---|---|
| v2.1.0-Preview | 2026年 6 月 |
- 基于HLIELLama支持好如下特性: - 投机解码支持(Draft Model/MTP)【实验特性】 - Qwen3.6/Qwen3.5全系列模型的推理优化 - CoPaw系列模型的支持 - Gamma4系列模型的支持 - Qwen3 Embedding和Reranker模型的支持 - GLM-OCR的模型支持 - Qwen3-asr、GLM-asr语音模型的支持 |
| v2.0.0 | 2026 年 5 月 | - 支持tts模型的推理通道及tts相关接口协议(cosyvoice3) - 支持语音模型的WebSocket协议输出(whisper) - GPT OSS模型的think参数支持 - 支持Qwen3.5系列文本和多模态模型的推理 - 支持--list-devices --dev 绑卡 - 支持qwen3-embedding, qwen3-rerank,qwen3.5 模型。 |
| v1.7.0 |
2026 年 3 月 | - 更新版本v1.0.0 - 支持语音识别相关接口协议的实现 - 支持bge模型的推理 - 支持Lora模型 - 集成HLIEWhisperCpp支持whisper语音模型 - 支持多卡、多模型同时运行和负载分发 |
| v1.6.0 | 2026年 1 月 | - 更新版本v0.0.7 - 单用户多轮对话场景下支持kv cache复用 - 支持VL模型自动匹配 - 更新默认加载模型配置方式 |
| v1.6.0-alpha |
2025年 12 月 | - 支持Qwen3-30B-A3B模型【M50】 - 支持Qwen3-Coder-30B-A3B模型【M50】 - 支持Qwen3 VL 4B模型【M30】【M50】 - 支持Qwen3 VL 8B模型【M50】 - 支持参数MinP, presence_penalty |
| v1.5.0 |
2025 年 10 月 13 日 | - 新增配置与管理UI界面,并对接HLAWModel,支持模型推理调度,支持NPU状态的查询 - 多batch能力支持 - 支持服务空载运行,模型通过 RestfulAPI请求进行动态下发与卸载,支持多实例场景 - 修复遗留jira bug - 思维链开关更新 |
| v1.4.0 |
2025年08月20日 | - 切换依赖到自研定制版llama.cpp - 支持文本+文生图(Xh2+SD3) - 支持单进程同时文本+文生图 - 支持多进程(多实例)启动,适配负载均衡 - Request日志独立 - 支持Qwen2.5VL - 支持从hi.cpp配置文件配置tcim日志级别 |
| v1.3.0 |
2025年06月30日 | - Windows安装包支持HiBalancer 多卡部署 - Windows服务Boot日志功能 - Request日志优化 |
| v1.3.0-daily-20250625-m50 | 2025年06月12日 | 支持sampling开关配置 |
| v1.3.0-daily-20250618-m50 | 2025年06月12日 | 支持M50测试版本, 增加性能数据日志记录 |
| v1.3.0-daily-20250612-m50 | 2025年06月12日 | 支持M50测试版本 |
| v1.3.0-daily-20250606 | 2025年06月06日 | 支持以linux后台service服务形式跑hi.cpp推理服务,能以openai api对外提供能力,同时提供麒麟OS对应版本的SDk,操作系统支持麒麟OS v10,模型包括qwen3 8b和deepseek 7b |
| v1.3.0-daily-20250530 | 2025年05月30日 | 支持4cores_8k qwen3-8b-1batch |
| 1.2.0 |
2025年05月30日 | 实现Windows服务化安装,兼容更多OpenAI 接口参数,增加端口配置和日志Level与路径配置 |
| 1.1.0 | 2024年04月11日 | 正式版本 |
| 1.1.0 | 2024年07月19日 | 更新软件版本 |
| 1.0.0 | 2024年07月10日 | 正式版本 |
本文档将带你快速连接并启动HLIECpp推理服务。
CPU结构:x86_64
硬盘:200G
操作系统:Windows 11/10
注意
安装本系统前请确保已安装好推理AI 卡
2.1.0 版本之后,HLIECpp 安装集成在 AI 助手的应用市场内。
在零刻AI网站推理框架栏目下载安装包(https://llm.bee-link.cn/frameworks.php),下载并双击 HLAWUtility-Setup-1.4.0-win-x64.exe 安装包,进入安装过程。
准备界面过了之后,就可以选择安装目录了
HLAWUtility 提供了诸多功能项目方便使用者快速上手,包括
卡状态监测、模型管理(本地和云上)、配置管理、推理调度、驱动管理、固件(卡)管理。
总览首页如上所示,具体功能将在后续章节详细介绍。
切换到应用市场 ,找到 HLIECpp 直接点击安装。
下面的弹窗点击 Yes
等待若干秒即会出现安装完成的状态。
完整包名称为:HiModel_<target>_<model_type> [-vl]_<param_size>_p256_<context_size>_<batch_size>_<core_num>_<device_size>_<sys_version>_<build_time>.gguf
target 表示运行的硬件平台,如 xh1, xh2
model_type 表示模型类型
deepseek:表示该模型部署包为DeepSeek-r1 模型
qwen2.5:表示该模型部署包为QWen2.5 模型
qwen3:表示该模型部署包为QWen3 模型
其他模型类型...
[-vl] 表示多模态
param_size 表示模型参数,如4b
context_size 表示上下文大小,如2K
batch_size 表示模型支持的批量推理的能力大小,如 1b, 2b
core_num 表示模型构建适配的硬件的 IPU Core 数量,如2core
device_size 表示模型加载与推理需要几张AI Chip ,如1chip, 2chips (旧格式 1d, 2d)
sys_version表示模型编译基于硬件版本号,如 v0.7.0
build_time表示构建时间,如20260105154602
如 HiModel_xh2_qwen3_32b_256_32k_b1_4chips_2cores_v0.7.0_20251228.gguf
请在使用服务的过程中尽量保持模型文件的名称完整性
方式 1:
用户可在指定模型网站下载,如下:https://llm.bee-link.cn/
方式 2(推荐):
使用 HLAWUtility 工具的模型管理直接下载至本地模型目录:
如下图进入模型管理,模型列表中最左边如果是磁盘图标即为本地已有模型,云朵为云上模型且未下载。
找到所需模型,可以在 Operation 里面点击查看详情,或者直接下载。下载任务将会传递到任务中心,进行下载。
由于目前 SD3模型的特殊性,暂时只支持手动下载后进行建立 json 信息文件进行配置。
如下 SD3生图模型目录信息
models/ $ tree . ├── SD3 │ ├── clip.hmm │ ├── clip_l.hmm │ ├── mmdit.hmm │ ├── t5.hmm │ └── vae.hmm └── sd3.json ...
创建json文件描述SD3模型信息
{
"ModelType" : "Sd3",
"XHVersion" : 2,
"ClipModel" : "./SD3/clip.hmm",
"ClipLModel" : "./SD3/clip_l.hmm",
"T5Model" : "./SD3/t5.hmm",
"MMDitModel" : "./SD3/mmdit.hmm",
"VaeModel" : "./SD3/vae.hmm"
}
保存为包含 sd3 字样的 json 文件到配置好的模型目录。
配置文件位于安装目录(默认: C:\Program Files\AI\HLIECpp)的config下面,sys.cfg
[server] port=7901 # 设备ID, 以数字表示,默认只有0,多个设备用逗号隔开, 如 0,1 devices=0 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=1 # 用于多实例场景下节省内存使用,true时多实例的模型加载会有一定时间等待,达成串行效果 memory_saving=false [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 location=C:\ProgramData\AI\HLIECpp\logs\ [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] # 模型目录 cur_model=D:\models # 默认LLM/WHISPER模型,不带格式后缀 default= default_mmproj= # 是否默认加载SD3 enable_sd3=true # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
修改配置后,需要重启HLIECpp Service, 可以打开Windows服务,找到HLIECpp Service,然后右键进行重启。
打开应用后,我们切换到服务配置项,可以在里面修改需要的配置,然后点击保存并确认,并重启服务。
目前,后端API默认访问端口为7901,可以通过配置修改(需重启服务)。
如果是多实例常见,端口会依次+1,比如4个实例 端口分别是 7901,7902,7903,7904
目前服务在不配置默认模型的场景下支持空载运行,支持动态加载与卸载模型。
*###start
POST*http://localhost:7901/models/load
Content-Type:application/json {
"model": "HiModel_xh2_qwen3_32b_256_32k_b1_4chips_2cores_v0.7.0_20251228"
}
注意这里的端口 7901 主要是使用默认服务主进程的配置,有以下场景:
1)如果是多卡场景,需要动态实现多个进程实例,可以直接继续发到这个端口,主进程会 fork 出slave 进程来加载模型。
2)如果已有 llm模型,同时想启动 sd3 文生图,也可以直接
*###startSD
POST*http://localhost:7901/models/load
Content-Type:application/json {
"devices": "1",
"model_type": "sd",
"params": {
"vae_model": "D:/workspace/models/SD3/vae.hmm",
"t5_model": "D:/workspace/models/SD3/t5.hmm",
"clip_model": "D:/workspace/models/SD3/clip.hmm",
"clip_l_model": "D:/workspace/models/SD3/clip_l.hmm",
"mmdit_model": "D:/workspace/models/SD3/mmdit.hmm",
}
}
上面的 devices 执行了卡 1, 如果不想自己指定,可以直接配置 "devices": "undefined", 服务会自动在已有 Devices里面进行分配。
*POST*http://10.65.35.16:7901/models/unload
Content-Type:application/json {
"model_type": "llm"
}
注意这里的端口 7901是根据推理服务各个进程实例来配置的
*###stop
POST*http://localhost:7901/hlie/v1/stop
Content-Type:application/json {
"instance_id": 0,
"process_id": 0
}
如果 instance_id 是 0 那么是停止主进程的所有模型,全部卸载。
如果instance_id > 0, process_id > 0, 主进程会去找子进程然后 kill 掉进程。
注意,接口不会杀死主进程,只会卸载主进程的所有模型,主进程是常驻的。
*###status GET*http://localhost:7901/hlie/v1/status Content-Type:application/json
如下图所示,在推理调度项目中,可以将左边列表中已经下载好的本地模型,拖拽到后面的服务里面的 LLM 框内,实现推理服务加载模型操作。
如下图所示,可以切换到推理调度项,然后刷新完成后将模型列表中的对应模型拖拽至右侧的Drop model here 中。
如上图出现说明已经加载完成,黄色按钮可以用来卸载模型。(7901表示端口)
配置文件sys.cfg中的 model 区域中存在auto_load配置,默认为 true, 相关Completions/Embeddings会根据接口中的model参数去自动加载模型并响应对应的请求。
[model] cur_model=D:\workspace\models\ default = HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=true # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
推理服务在终端提供实时日志信息,如果启动服务过程中出现错误,可查看相关日志信息进行简单排错;并且请求和响应数据对通过输出到日志文件进行后续查看和问题排查,可以将日志以.log形式存放在log文件夹内。
log文件路径默认在C:\ProgramData\AI\HLIECpp\logs\
可以直接通过 HLAWUtility 主页面的日志目录按钮直达,
日志文件为 [type]-[instance-id]-[YYYY-MM-DD].log
type目前分为access与-llm
access 为HTTP请求日志
-llm为业务日志
sys.cfg
[server] port=7901 # 设备ID, 以数字表示,多个设备用逗号隔开 devices=0, 1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=1 [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 location=C:\ProgramData\AI\HLIECpp\logs\ [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] cur_model=D:\workspace\models\ default = HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=true # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
模型目录 D:\workspace\models\
{
"ModelType" : "SD3",
"MMDitModel" : "SD3/mmdit.hmm",
"ClipModel" : "SD3/clip.hmm",
"ClipLModel" : "SD3/clip_l.hmm",
"T5Model" : "SD3/t5.hmm",
"VaeModel" : "SD3/vae.hmm"
}
如上配置就可以实现在两张卡上加载文本+文生图模型,可以同时推理。
其中配置文件中的default_mmproj 可以留空,因为服务会自动根据 name 匹配到对应的 mmproj 文件,如果存在多个同版本&同构建时间不同分辨率的 mmproj,则需要指定到具体 mmproj 名称。
此时我们只需要在HLChatDesktop 上面分别配置对应模型Provider就可以同时进行文本与文生图聊天。
sys.cfg
如下replicas = 2,表示要启动两个进程,加载同一个模型
内存有限的机器可以配置 memory_saving = true 进行测试
[server] port=7901 # 设备ID, 以数字表示,多个设备用逗号隔开 devices=0, 1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=2 # 用于多实例场景下节省内存使用,true时多实例的模型加载会有一定时间等待,达成串行效果 memory_saving=true [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 location=C:\ProgramData\AI\HLIECpp\logs\ [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] # 模型目录 cur_model=D:\workspace\models\ # 默认LLM/WHISPER模型,不带格式后缀 default=HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=false # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
当前多实例需要与对应设备数量进行平均分配,比如有2张卡,针对2个实例的场景,那么每一个实例只能分到一张
*// 每个实例获取的NPU数量, 因为每个实例可以同时运行生文和生图 int *acquires_count = device_count / replicas;
Embedding 模型目前加载方式与 LLM 一致,支持的模型有bge 和 gte 类型,如下 HiModel_xh2_bge-m3_1.1b_512_512_b10_1chip_2cores_v0.7.0_20251231.gguf
HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228.gguf
使用方式:
如下在sys.cfg配置文件中修改default模型使用 HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228
也可在 HLAWUtility推理调度中加载
模型名称中请包含有 bge 或者gte 字段
[model] cur_model=D:\workspace\models\ default = HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=false # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
然后重启HLIECpp服务。
支持接口 : /embeddings, /v1/embeddings (OpenAI 兼容)
POST 示例:
POSThttp://localhost:7901/v1/embeddings
Content-Type:application/json {
"model": "HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228",
"input": "这是一段测试的文本",
"n_tokens": 5
}### start
POSThttp://localhost:7901/hlie/v1/start
Content-Type:application/json {
"devices": "1",
"model": "HiModel_xh2_qwen3-vl_4b_256_32k_b1_1chip_2cores_v0.7.0_20251220",
}
以上场景需要在HLIECpp的sys.cfg中有对应的卡配置
[server] port=7901 # 设备ID, 以数字表示,多个设备用逗号隔开 devices=0,1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 ### 其他配置 ### ......
根据 2.3 章节说到的服务配置文件可以看到 llm_params Section 可以添加 llama相关参数配置
如 --repeat-penalty ,--presence-penalty,--frequency-penalty,--repeat-last-n,--top-k,--top-p,--temp 等
sys.cfg
#之前的配置 [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 #继续之后的内容
可以在配置文件中的 llm_params 区域内添加参数 --reasoning_budget = 0 就可以避免深度思考
#之前的配置 [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none --reasoning_budget=0 #继续之后的内容
| 参数 | 含义 | 作用机制 | 常见取值范围 | 效果 |
|---|---|---|---|---|
| --repeat-penalty | 重复惩罚系数 | 如果模型重复输出相同的 token,就降低这些 token 的概率 | 1.0 \~ 1.5 | 越大越避免重复,但太大会导致输出断裂或奇怪词汇 |
| --presence-penalty | 存在惩罚 | 如果某个 token 已经出现过,就降低它再次出现的概率 | 0.0 \~ 2.0 | 增加主题覆盖面,减少重复,但可能偏离话题 |
| --frequency-penalty | 频率惩罚 | 按某个 token 出现的次数来惩罚 | 0.0 \~ 2.0 | 控制重复词汇,避免“叠词”现象 |
| --repeat-last-n | 重复检测范围 | 在最近 N 个 token 中启用重复惩罚 | 0 \~ 4096 | 越大 → 更全局防重复;太大会增加惩罚力度,影响流畅性 |
| --top-k | Top-K 采样 | 只在概率最高的 K 个候选中选择下一个 token | 20 \~ 100 | 限制选择空间,过大容易啰嗦,过小可能死板 |
| --top-p | Top-P (核采样) | 只保留概率累积 ≤ P 的候选,然后随机选择 | 0.7 \~ 0.95 | 越大越多样化,越小越确定 |
| --temp | 温度 | 控制概率分布的平滑度 | 0.2 \~ 1.5 | 越大越随机,越小越保守 |
📑 会议纪要(追求稳定、少废话)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --reasoning_budget = 0 --repeat-penalty = 1. 2 --presence-penalty = 0. 2 --frequency-penalty = 0. 2 --repeat-last-n = 256 --top-k = 40 --top-p = 0. 9 --temp = 0. 5
✍️ 文稿撰写(需要创意和多样性)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --reasoning_budget = 0 --repeat-penalty = 1. 05 --presence-penalty = 0. 8 --frequency-penalty = 0. 5 --repeat-last-n = 512 --top-k = 80 --top-p = 0. 95 --temp = 0. 8
🤖 聊天机器人(自然、互动性强)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --repeat-penalty = 1. 1 --presence-penalty = 0. 6 --frequency-penalty = 0. 3 --repeat-last-n = 256 --top-k = 50 --top-p = 0. 9 --temp = 0. 7
现已支持模型 Whisper-Medium 与 Whisper-Large-v3-Turbo。
可以从模型管理中下载对应模型,如
Curl 命令:
curl -X POST "http://localhost:7901/hlie/v1/start" \
-H "Content-Type: application/json" \
-d '{ "model_type": "whisper", "model": "HiModel_xh2_whisper-medium_1.5b_256_1chip_2cores_v1.0.0_20260228" }'
AI 助手:
curl-XPOST "http://127.0.0.1:7901/v1/audio/transcriptions" \ -H "Content-Type: multipart/form-data" \ -F"file=@E:/test_data/audio/long_2.wav"
可以使用相关脚本或者服务连接"ws://127.0.0.1:7999"
然后按顺序发送音频 float32类型字节流并以字符串 EOS 结尾,进行推理。
参考Python 脚本:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- *"""*
* Whisper.cpp / miniaudio Compatible WebSocket Audio Stream Client* *功能:*
* 1. 读取 wav 音频*
* 2. 转 mono*
* 3. 重采样到 16k*
* 4. 转 float32 PCM [-1,1]*
* 5. websocket 流式发送* * 目标:*
* 与 whisper.cpp 中 miniaudio 的行为尽可能一致* * 数据格式:*
* float32 PCM*
* 16000Hz*
* mono* *发送协议:*
* binary:*
* float32 PCM bytes* * text:*
* EOS*
* """* import asyncio
import time
from pathlib import Path import numpy as np
import soundfile as sf
import websockets
from loguru import logger
from scipy import signal # ============================================================================= # Config # ============================================================================= TARGET_SAMPLE_RATE = 16000 # 1000ms chunk
CHUNK_DURATION_MS = 1000 # websocket uri
WS_URI = "ws://10.65.32.191:7999" # audio file
AUDIO_FILE = "D:/workspace/wtt//llm/hi.cpp/samples/zero_shot_prompt.wav" # ============================================================================= # Logger # ============================================================================= logger. remove () logger. add ( sink=lambda msg : print (msg, end=""), level="INFO", format=( "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | " "<level>{level: </level> | " "{message}" ),) logger. add ( "asr_websocket_test.log", level="DEBUG", rotation="10 MB", retention=5, encoding="utf-8",) # ============================================================================= # Audio Process # ============================================================================= def load_audio (file_path : str) -> np. ndarray : *"""*
* 加载音频并转换成:* * float32*
* mono*
* 16000Hz*
* [-1,1]* * 尽量模拟 miniaudio 行为*
* """* * *logger. info (f"Loading audio:{file_path}") # soundfile: # int16 wav -> int16 # float wav -> float data, sample_rate = sf. read (file_path) logger. info ( f"Original audio info: " f"sample_rate={sample_rate}, " f"shape={data.shape}, " f"dtype={data.dtype}" ) # ========================================================================= # Convert to mono # ========================================================================= if data. ndim > 1 : logger. info ( f"Convert multi-channel -> mono " f"(channels={data.shape[1]})" ) # IMPORTANT: # whisper.cpp/miniaudio: # left + right # # NOT: # (left + right) / 2 # # 这里使用 sum 更接近 whisper.cpp data = np. sum (data, axis=1) # ========================================================================= # Resample to 16k # ========================================================================= if sample_rate != TARGET_SAMPLE_RATE : logger. info ( f"Resample audio: " f"{sample_rate}Hz ->{TARGET_SAMPLE_RATE}Hz" ) num_samples = int ( len (data) * TARGET_SAMPLE_RATE / sample_rate ) data = signal. resample ( data, num_samples,) sample_rate = TARGET_SAMPLE_RATE # ========================================================================= # Convert to float32 # ========================================================================= if data. dtype == np. int16 : logger. info ("Convert int16 -> float32") data = data. astype (np. float32) / 32768.0 elif data. dtype == np. int32 : logger. info ("Convert int32 -> float32") data = data. astype (np. float32) / 2147483648.0 elif data. dtype != np. float32 : logger. info (f"Convert{data.dtype} -> float32") data = data. astype (np. float32) # ========================================================================= # Clip # ========================================================================= # 防止 stereo 相加后超过 [-1,1] data = np. clip (data, -1.0, 1.0) duration = len (data) / TARGET_SAMPLE_RATE logger. success ( f"Audio ready: " f"samples={len(data)}, " f"duration={duration:.2f}s, " f"dtype={data.dtype}" ) return data # ============================================================================= # WebSocket Stream # ============================================================================= async def stream_audio ( websocket, pcmf32 : np. ndarray,): *"""*
* websocket 流式发送 float32 PCM*
* """* * *chunk_size = int ( TARGET_SAMPLE_RATE * CHUNK_DURATION_MS / 1000 ) total_chunks = ( len (pcmf32) + chunk_size - 1 ) // chunk_size logger. info ( f"Start streaming: " f"chunk_duration={CHUNK_DURATION_MS}ms, " f"chunk_size={chunk_size}, " f"total_chunks={total_chunks}" ) start_time = time. time () for chunk_index, start in enumerate ( range (0, len (pcmf32), chunk_size), start=1,): end = start + chunk_size chunk = pcmf32 [start : end] # binary float32 pcm binary = chunk. astype (np. float32). tobytes () await websocket. send (binary) chunk_duration = ( len (chunk) / TARGET_SAMPLE_RATE ) logger. info ( f"[Chunk{chunk_index}/{total_chunks}] " f"samples={len(chunk)}, " f"bytes={len(binary)}, " f"duration={chunk_duration:.3f}s" ) # 模拟真实实时发送 await asyncio. sleep (chunk_duration) elapsed = time. time () - start_time logger. success ( f"Audio stream completed (elapsed={elapsed:.2f}s)" ) # ============================================================================= # Main # ============================================================================= async def simulate_frontend_stream ( file_path : str, uri : str,): if not Path (file_path). exists (): logger. error ( f"Audio file not found:{file_path}" ) return # load audio pcmf32 = load_audio (file_path) logger. info (f"Connecting websocket:{uri}") try : async with websockets. connect ( uri, max_size=20 * 1024 * 1024, ping_interval=20, ping_timeout=20,) as websocket : logger. success ("WebSocket connected") # stream audio await stream_audio ( websocket, pcmf32,) # EOS logger. info ("Sending EOS") await websocket. send ("EOS") # wait result logger. info ("Waiting ASR result...") result = await asyncio. wait_for ( websocket. recv (), timeout=30.0,) logger. success ( f"ASR Result:\n{result}" ) except asyncio. TimeoutError : logger. error ( "Timeout waiting ASR result" ) except websockets. ConnectionClosed as e : logger. error ( f"WebSocket closed: " f"code={e.code}, " f"reason={e.reason}" ) except Exception as e : logger. exception ( f"Unexpected error:{e}" ) finally : logger. info ("Test finished") # ============================================================================= # Entry # ============================================================================= if __name__ == "__main__" : asyncio. run ( simulate_frontend_stream ( AUDIO_FILE, WS_URI,) )TTS目前仅支持了 CosyVoice3 模型
Curl 命令:
curl -X POST "http://localhost:7901/hlie/v1/start" \
-H "Content-Type: application/json" \
-d '{ "model_type": "cosyvoice", "model": "HiModel_xh2_cosyvoice3_0.5b_1chip_2cores_v1.1.0-20260409" }'
AI 助手:
curl -X POST "http://localhost:7901/v1/audio/speech" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{ "input": "君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪!人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。岑夫子,丹丘生,将进酒,杯莫停。与君歌一曲,请君为我倾耳听。钟鼓馔玉不足贵,但愿长醉不复醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马、千金裘,呼儿将出换美酒,与尔同销万古愁!", "prompt_wav_path": "E:/test_data/tts/zero_shot_0.wav", "prompt_text": "八百标兵奔北坡,北坡炮兵并排跑,炮兵怕把标兵碰,标兵怕碰炮兵炮。" }'
上述参数其中prompt_wav_path的音频必须与 promt_text的文字一一对齐,当然这两个参数也可以都不需要,如:
下面这种方式,在推理时会使用系统自带的默认的prompt。
curl -X POST "http://localhost:7901/v1/audio/speech" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{ "input": "君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪!人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。岑夫子,丹丘生,将进酒,杯莫停。与君歌一曲,请君为我倾耳听。钟鼓馔玉不足贵,但愿长醉不复醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马、千金裘,呼儿将出换美酒,与尔同销万古愁!" }'安装失败:可以检查当前用户对于C盘的操作权限,确保默认可以新建文件
启动失败:
查看对应日志
默认的服务日志路径是: C:\ProgramData\AI\HLIECpp\logs\
默认的系统日志路径是:C:\Program Files\AI\HLIECpp\bin\boot_log
Debug Console
打开命令提示行,定位到安装目录的 bin 目录位置,执行 debug.bat
C:\Program Files\AI\HLIECpp\bin\debug.bat
执行之后查看是否有意外错误等信息。
接口失败:查看返回消息&系统日志
其他无法定位问题请联系
| 版本 | 日期 | 描述 |
|---|---|---|
| v2.1.0-Preview | 2026年 6 月 | - 基于HLIELLama支持好如下特性: - 投机解码支持(Draft Model/MTP)【实验特性】 - Qwen3.6/Qwen3.5全系列模型的推理优化 - CoPaw系列模型的支持 - Gamma4系列模型的支持 - Qwen3 Embedding和Reranker模型的支持 - GLM-OCR的模型支持 - Qwen3-asr、GLM-asr语音模型的支持 |
| v2.0.0 | 2026 年 5 月 | - 支持tts模型的推理通道及tts相关接口协议(cosyvoice3) - 支持语音模型的WebSocket协议输出(whisper) - GPT OSS模型的think参数支持 - 支持Qwen3.5系列文本和多模态模型的推理 - 支持--list-devices --dev 绑卡 - 支持qwen3-embedding, qwen3-rerank,qwen3.5 模型。 |
| v1.7.0 | 2026 年 3 月 | - 更新版本v1.0.0 - 支持语音识别相关接口协议的实现 - 支持bge模型的推理 - 支持Lora模型 - 集成HLIEWhisperCpp支持whisper语音模型 - 支持多卡、多模型同时运行和负载分发 |
| v1.6.0 | 2026年 1 月 | - 单用户多轮对话场景下支持kv cache复用 - 支持VL模型自动匹配 - 更新默认加载模型配置方式 |
| v1.6.0-alpha |
2025年 12 月 | - 支持Qwen3-30B-A3B模型【M50】 - 支持Qwen3-Coder-30B-A3B模型【M50】 - 支持Qwen3 VL 4B模型【M30】【M50】 - 支持Qwen3 VL 8B模型【M50】 - 支持参数MinP, presence_penalty |
| 1.5.0 | 20251013 | - 新增配置与管理UI界面,并对接HLAWModel,支持模型推理调度,支持NPU状态的查询 - 多batch能力支持 - 支持服务空载运行,模型通过 RestfulAPI请求进行动态下发与卸载,支持多实例场景 - 修复遗留jira bug - 思维链开关更新 |
| 1.4.0 | 20250815 | - 切换依赖到自研定制版llama.cpp - 支持文本+文生图(Xh2+SD3) - 支持多实例部署 - Request日志独立 - 支持Qwen2.5VL - 支持从hi.cpp配置文件配置tcim日志级别 |
| 1.3.0 | 20250606 | run包支持ubunut2004、麒麟v10 sp1 增加demo示例和说明 |
本文档将带你快速连接并启动linux平台推理服务。
完整包名称为:HiModel-<model_type> [-vl]-<param_size>-p256-<context_size>-<batch_size>-<core_num>-<device_size>-<target>-<sys_version>-<build_time>.gguf
model_type 表示模型类型
DeepSeek:表示该模型部署包为DeepSeek-r1 模型
Qwen2.5:表示该模型部署包为QWen2.5 模型
Qwen3:表示该模型部署包为QWen3 模型
[-vl] 表示多模态
param_size 表示模型参数,如4b
context_size 表示上下文大小,如2K
batch_size 表示模型支持的批量推理的能力大小,如 1b, 2b
core_num 表示模型构建适配的硬件的 IPU Core 数量,如2core
device_size 表示模型加载与推理需要几张AI Chip ,如1d, 2d
target 表示运行的硬件平台,如 xh1, xh2
sys_version表示模型编译基于硬件版本号,如 v0.7.0
build_time表示构建时间,如20260105154602
如 HiModel-Qwen3-vl-4b-p256-2K-b1-2core-1d-xh2-v0.7.0-20260105154602.gguf
请在使用服务的过程中尽量保持模型文件的名称完整性
用户可在指定模型网站下载,如下:https://llm.bee-link.cn/
HLIECpp 模型包目前基于llama-cpp 模型,使用GGUF 格式
models/ $ tree . |-- HiModel-Qwen3-8b-p256-2K-b1-2core-1d-xh2-v0.7.0-20260105154602.gguf
手动配置SD3模型(若不需要可跳过)
由于目前 SD3模型的特殊性,暂时只支持手动下载后进行建立 json 信息文件进行配置。
如下 SD3生图模型目录信息
models/ $ tree . ├── SD3 │ ├── clip.hmm │ ├── clip_l.hmm │ ├── mmdit.hmm │ ├── t5.hmm │ └── vae.hmm └── sd3.json ...
创建json文件描述SD3模型信息
{
"ModelType" : "Sd3",
"XHVersion" : 2,
"ClipModel" : "./SD3/clip.hmm",
"ClipLModel" : "./SD3/clip_l.hmm",
"T5Model" : "./SD3/t5.hmm",
"MMDitModel" : "./SD3/mmdit.hmm",
"VaeModel" : "./SD3/vae.hmm"
}
保存为包含 sd3 字样的 json 文件到配置好的模型目录。
加载模型的路径,通过配置文件指定,如需修改,更改下面路径sys.cfg文件中的cur_model 值
/opt/``HLIECpp``/config/sys.cfg
[server] port=7901 # 设备ID, 以数字表示,默认只有0,多个设备用逗号隔开, 如 0,1 devices=0 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=1 # 用于多实例场景下节省内存使用,true时多实例的模型加载会有一定时间等待,达成串行效果 memory_saving=false [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 # Just for Windows Mode, Linux Service use fixed path: /var/log//HLIECpp location=/var/log//HLIECpp # SDK & Demo using open_console_window=true [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] # 模型目录 cur_model=/opt//models # 默认LLM/WHISPER模型,不带格式后缀 default=HiModel-Qwen3-vl-4b-p256-2K-b1-2core-1d-xh2-v0.7.0-20260105154602 default_mmproj= # 是否默认加载SD3 enable_sd3=false # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
其中配置文件中的default_mmproj 可以留空,因为服务会自动根据 name 匹配到对应的 mmproj 文件,如果存在多个同版本&同构建时间不同分辨率的 mmproj,则需要指定到具体 mmproj 名称。
修改完成后:重启hicpp服务
sudo systemctl daemon-reload
sudo systemctl restart HLIECpp.service
从零刻AI网站推理框架栏目下载对应平台的安装 run 包(https://llm.bee-link.cn/frameworks.php)。如下是 Linux x86_64 平台的安装包:
sudo ./houmo-HLIECpp_xh2_2_1_0_linux_x86_64.run
安装完成后,推理服务默认就会开启。执行下面的命令,查看推理服务是否正常启动:
sudo systemctl status HLIECpp
注意:尤其要确认第 2 章中 models 文件夹的路径和内容正确,否则上面的命令会输出 loadmodel 失败之类的错误提示。
sudo systemctl start HLIECpp # 启动服务(安装 run 包后默认已开启,无需再 start)
sudo systemctl stop HLIECpp # 停止服务
sudo systemctl restart HLIECpp # 重启服务
sudo systemctl status HLIECpp # 查看状态
sudo systemctl stop HLIECpp
sudo systemctl disable HLIECpp
sudo rm /etc/systemd/system/HLIECpp.service
sudo systemctl daemon-reload
下面的命令看情况是否需要执行,尤其 model 模型文件很大,不要轻易删除:
sudo rm -rf /opt/HLIECpp
API访问地址:http://ip:7901
目前,后端API默认访问端口为7901,可以通过配置文件修改(需重启)。
如果是多实例常见,端口会依次+1,比如4个实例 端口分别是 7901,7902,7903,7904
目前服务在不配置默认模型的场景下支持空载运行,支持动态加载与卸载模型。
*POSThttp://localhost:7901/models/load
Content-Type:application/json {
"model": "HiModel-Qwen3-vl-4b-p256-2K-b1-2core-1d-xh2-v0.7.0-20260105154602"
}*
注意这里的端口 7901 主要是使用默认服务主进程的配置,有以下场景:
1)如果是多卡场景,需要动态实现多个进程实例,可以直接继续发到这个端口,主进程会 fork 出slave 进程来加载模型。
2)如果已有 llm模型,同时想启动 sd3 文生图,也可以直接
*POSThttp://localhost:7901/models/load
Content-Type:application/json {
"devices": "1",
"model_type": "sd",
"params": {
"vae_model": "SD3/vae.hmm",
"t5_model": "SD3/t5.hmm",
"clip_model": "SD3/clip.hmm",
"clip_l_model": "SD3/clip_l.hmm",
"mmdit_model": "SD3/mmdit.hmm",
}
}*
上面的 devices 执行了卡 1, 如果不想自己指定,可以直接配置 "devices": "undefined", 或者不添加这个参数,服务会自动在已有 Devices里面进行分配。
*POSThttp://localhost:7901/hlie/v1/unload_model
Content-Type:application/json {
"model_type": "llm"
}*
curl-XPOSThttp://*localhost*:7901/hlie/v1/unload_model-H "Content-Type: application/json"-d '{"model_type": "llm"}'
注意这里的端口 7901是根据推理服务各个进程实例来配置的
*POST*http://localhost:7901/hlie/v1/stop
Content-Type:application/json {
"instance_id": 0,
"process_id": 0
}
如果 instance_id 是 0 那么是停止主进程的所有模型,全部卸载。
如果instance_id > 0, process_id > 0, 主进程会去找子进程然后 kill 掉进程。
注意,接口不会杀死进程,只会卸载主进程的所有模型。
*GET*http://localhost:7901/hlie/v1/status Content-Type:application/json
sys.cfg
[server] port=7901 # 设备ID, 以数字表示,默认只有0,多个设备用逗号隔开, 如 0,1 devices=0,1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=1 # 用于多实例场景下节省内存使用,true时多实例的模型加载会有一定时间等待,达成串行效果 memory_saving=false [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 # Just for Windows Mode, Linux Service use fixed path: /var/log//HLIECpp location=/var/log//HLIECpp # SDK & Demo using open_console_window=true [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] cur_model=/opt//models default=HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=true # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
模型目录 /opt//models 中需要包含HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228.gguf
sd3_model.json
{
"ModelType" : "SD3",
"MMDitModel" : "SD3/mmdit.hmm",
"ClipModel" : "SD3/clip.hmm",
"ClipLModel" : "SD3/clip_l.hmm",
"T5Model" : "SD3/t5.hmm",
"VaeModel" : "SD3/vae.hmm"
}
此时我们只需要在HLChatDesktop 上面分别配置对应模型Provider就可以同时进行文本与文生图聊天。
sys.cfg
如下replicas = 2,表示要启动两个进程并加载同一个模型
内存有限的机器可以配置 memory_saving = true 进行测试
[server] port=7901 # 设备ID, 以数字表示,默认只有0,多个设备用逗号隔开, 如 0,1 devices=0,1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 replicas=2 # 用于多实例场景下节省内存使用,true时多实例的模型加载会有一定时间等待,达成串行效果 memory_saving=false [log] # debug, info, warn, info level=info # 4-debug, 3-warn, 2-error 1-info tcim_level=2 # max files to keep max_files=7 # Just for Windows Mode, Linux Service use fixed path: /var/log//HLIECpp location=/var/log//HLIECpp # SDK & Demo using open_console_window=true [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja= --reasoning-format=none #--reasoning_budget = 0 [model] cur_model=/opt//models # 默认LLM/WHISPER模型,不带格式后缀 default=HiModel_xh2_qwen3_8b_256_16k_b4_1chip_2cores_v0.7.0_20251228 # 是否默认加载SD3 default_mmproj= enable_sd3=false # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
当前多实例需要与对应设备数量进行平均分配,比如有2张卡,针对2个实例的场景,那么每一个实例只能分到一张
*// 每个实例获取的NPU数量, 因为每个实例可以同时运行生文和生图 int *acquires_count = device_count / replicas;
将对应的模型下载到模型指定目录:
如 /opt//models 下面有:
HiModel_xh2_qwen3-vl_4b_256_32k_b1_1chip_2cores_v0.7.0_20251228.gguf
mmproj_xh2_qwen3-vl_4b_2cores_vit_448x448_v0.7.0_20251228.gguf
如果需要默认跟随服务启动,则在 sys.cfg 的中[model] 下面的 default 字段修改成对应的主模型名字
[model] cur_model=/opt//models default=HiModel_xh2_qwen3-vl_4b_256_32k_b1_1chip_2cores_v0.7.0_20251228 default_mmproj= enable_sd3=false
其中配置文件中的default_mmproj 可以留空,因为服务会自动根据 name 匹配到对应的 mmproj 文件,如果存在多个同版本&同构建时间不同分辨率的 mmproj,则需要指定到具体 mmproj 名称。
Embedding 模型目前加载方式与 LLM 一致,支持的模型有bge 和 gte 类型,如下 HiModel_xh2_bge-m3_1.1b_512_512_b10_1chip_2cores_v0.7.0_20251231.gguf
HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228.gguf
使用方式:
如下在sys.cfg配置文件中修改default模型使用 HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228
也可在 HLAWUtility推理调度中加载
模型名称中请包含有 bge 或者gte 字段
[model] cur_model=/opt//models default=HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228 default_mmproj= # 是否默认加载SD3 enable_sd3=false # 针对LLM配置为true时,相关Completions/Embeddings会根据接口中的model参数去自动加载模型 auto_load=true # LLM模型懒加载 llm_lazy_mode=false
然后重启HLIECpp服务。
支持接口 : /embeddings, /v1/embeddings (OpenAI 兼容)
POST 示例:
POSThttp://localhost:7901/v1/embeddings
Content-Type:application/json {
"model": "HiModel_xh2_gte_1.5b_256_1chip_2cores_v0.7.0_20251228",
"input": "这是一段测试的文本",
"n_tokens": 5
}### start
POST http://localhost:7901/hlie/v1/start
Content-Type: application/json { "devices": "1", "model": "HiModel_xh2_qwen3-vl_4b_256_32k_b1_1chip_2cores_v0.7.0_20251220",
}
当然也可以依赖服务配置只配置 devices = 1
以上场景需要在HLIECpp的sys.cfg中有对应的卡配置
[server] port=7901 # 设备ID, 以数字表示,多个设备用逗号隔开 devices=0, 1 # 实例副本数量,会启动多个进程,端口会递增+1, 用于负载均衡,多个设备同时运行同一种模型 ### 其他配置 ### ......
服务配置文件可以看到 llm_params Section 可以添加 llama相关参数配置
如 --repeat-penalty ,--presence-penalty,--frequency-penalty,--repeat-last-n,--top-k,--top-p,--temp 等
sys.cfg
#之前的配置 [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 #--jinja = #--reasoning_budget = 0 #继续之后的内容
sys.cfg
#之前的配置 [llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 #--jinja = #--reasoning_budget = 0 #继续之后的内容
| 参数 | 含义 | 作用机制 | 常见取值范围 | 效果 |
|---|---|---|---|---|
| --repeat-penalty | 重复惩罚系数 | 如果模型重复输出相同的 token,就降低这些 token 的概率 | 1.0 \~ 1.5 | 越大越避免重复,但太大会导致输出断裂或奇怪词汇 |
| --presence-penalty | 存在惩罚 | 如果某个 token 已经出现过,就降低它再次出现的概率 | 0.0 \~ 2.0 | 增加主题覆盖面,减少重复,但可能偏离话题 |
| --frequency-penalty | 频率惩罚 | 按某个 token 出现的次数来惩罚 | 0.0 \~ 2.0 | 控制重复词汇,避免“叠词”现象 |
| --repeat-last-n | 重复检测范围 | 在最近 N 个 token 中启用重复惩罚 | 0 \~ 4096 | 越大 → 更全局防重复;太大会增加惩罚力度,影响流畅性 |
| --top-k | Top-K 采样 | 只在概率最高的 K 个候选中选择下一个 token | 20 \~ 100 | 限制选择空间,过大容易啰嗦,过小可能死板 |
| --top-p | Top-P (核采样) | 只保留概率累积 ≤ P 的候选,然后随机选择 | 0.7 \~ 0.95 | 越大越多样化,越小越确定 |
| --temp | 温度 | 控制概率分布的平滑度 | 0.2 \~ 1.5 | 越大越随机,越小越保守 |
📑 会议纪要(追求稳定、少废话)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --reasoning_budget = 0 --repeat-penalty = 1. 2 --presence-penalty = 0. 2 --frequency-penalty = 0. 2 --repeat-last-n = 256 --top-k = 40 --top-p = 0. 9 --temp = 0. 5
✍️ 文稿撰写(需要创意和多样性)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --reasoning_budget = 0 --repeat-penalty 1. 05 --presence-penalty 0. 8 --frequency-penalty 0. 5 --repeat-last-n 512 --top-k 80 --top-p 0. 95 --temp 0. 8
🤖 聊天机器人(自然、互动性强)
[llm_params] #llama-server的参数透传,请参考下面或者llamacpp的设置, 请使用完整option: --xxx = xx, 没有值的请留空 --jinja = --reasoning-format = none --repeat-penalty 1. 1 --presence-penalty 0. 6 --frequency-penalty 0. 3 --repeat-last-n 256 --top-k 50 --top-p 0. 9 --temp 0. 7
现已支持模型 Whisper-Medium 与 Whisper-Large-v3-Turbo。
可以从模型管理中下载对应模型,如
Curl 命令:
curl -X POST "http://localhost:7901/hlie/v1/start" \
-H "Content-Type: application/json" \
-d '{ "model_type": "whisper", "model": "HiModel_xh2_whisper-medium_1.5b_256_1chip_2cores_v1.0.0_20260228" }'
AI 助手:
curl-XPOST "http://127.0.0.1:7901/v1/audio/transcriptions" \ -H "Content-Type: multipart/form-data" \ -F"file=@E:/test_data/audio/long_2.wav"
可以使用相关脚本或者服务连接"ws://127.0.0.1:7999"
然后按顺序发送音频 float32类型字节流并以字符串 EOS 结尾,进行推理。
参考Python 脚本:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- *"""*
* Whisper.cpp / miniaudio Compatible WebSocket Audio Stream Client* *功能:*
* 1. 读取 wav 音频*
* 2. 转 mono*
* 3. 重采样到 16k*
* 4. 转 float32 PCM [-1,1]*
* 5. websocket 流式发送* * 目标:*
* 与 whisper.cpp 中 miniaudio 的行为尽可能一致* * 数据格式:*
* float32 PCM*
* 16000Hz*
* mono* *发送协议:*
* binary:*
* float32 PCM bytes* * text:*
* EOS*
* """* import asyncio
import time
from pathlib import Path import numpy as np
import soundfile as sf
import websockets
from loguru import logger
from scipy import signal # ============================================================================= # Config # ============================================================================= TARGET_SAMPLE_RATE = 16000 # 1000ms chunk
CHUNK_DURATION_MS = 1000 # websocket uri
WS_URI = "ws://10.65.32.191:7999" # audio file
AUDIO_FILE = "D:/workspace/wtt//llm/hi.cpp/samples/zero_shot_prompt.wav" # ============================================================================= # Logger # ============================================================================= logger. remove () logger. add ( sink=lambda msg : print (msg, end=""), level="INFO", format=( "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> | " "<level>{level: </level> | " "{message}" ),) logger. add ( "asr_websocket_test.log", level="DEBUG", rotation="10 MB", retention=5, encoding="utf-8",) # ============================================================================= # Audio Process # ============================================================================= def load_audio (file_path : str) -> np. ndarray : *"""*
* 加载音频并转换成:* * float32*
* mono*
* 16000Hz*
* [-1,1]* * 尽量模拟 miniaudio 行为*
* """* * *logger. info (f"Loading audio:{file_path}") # soundfile: # int16 wav -> int16 # float wav -> float data, sample_rate = sf. read (file_path) logger. info ( f"Original audio info: " f"sample_rate={sample_rate}, " f"shape={data.shape}, " f"dtype={data.dtype}" ) # ========================================================================= # Convert to mono # ========================================================================= if data. ndim > 1 : logger. info ( f"Convert multi-channel -> mono " f"(channels={data.shape[1]})" ) # IMPORTANT: # whisper.cpp/miniaudio: # left + right # # NOT: # (left + right) / 2 # # 这里使用 sum 更接近 whisper.cpp data = np. sum (data, axis=1) # ========================================================================= # Resample to 16k # ========================================================================= if sample_rate != TARGET_SAMPLE_RATE : logger. info ( f"Resample audio: " f"{sample_rate}Hz ->{TARGET_SAMPLE_RATE}Hz" ) num_samples = int ( len (data) * TARGET_SAMPLE_RATE / sample_rate ) data = signal. resample ( data, num_samples,) sample_rate = TARGET_SAMPLE_RATE # ========================================================================= # Convert to float32 # ========================================================================= if data. dtype == np. int16 : logger. info ("Convert int16 -> float32") data = data. astype (np. float32) / 32768.0 elif data. dtype == np. int32 : logger. info ("Convert int32 -> float32") data = data. astype (np. float32) / 2147483648.0 elif data. dtype != np. float32 : logger. info (f"Convert{data.dtype} -> float32") data = data. astype (np. float32) # ========================================================================= # Clip # ========================================================================= # 防止 stereo 相加后超过 [-1,1] data = np. clip (data, -1.0, 1.0) duration = len (data) / TARGET_SAMPLE_RATE logger. success ( f"Audio ready: " f"samples={len(data)}, " f"duration={duration:.2f}s, " f"dtype={data.dtype}" ) return data # ============================================================================= # WebSocket Stream # ============================================================================= async def stream_audio ( websocket, pcmf32 : np. ndarray,): *"""*
* websocket 流式发送 float32 PCM*
* """* * *chunk_size = int ( TARGET_SAMPLE_RATE * CHUNK_DURATION_MS / 1000 ) total_chunks = ( len (pcmf32) + chunk_size - 1 ) // chunk_size logger. info ( f"Start streaming: " f"chunk_duration={CHUNK_DURATION_MS}ms, " f"chunk_size={chunk_size}, " f"total_chunks={total_chunks}" ) start_time = time. time () for chunk_index, start in enumerate ( range (0, len (pcmf32), chunk_size), start=1,): end = start + chunk_size chunk = pcmf32 [start : end] # binary float32 pcm binary = chunk. astype (np. float32). tobytes () await websocket. send (binary) chunk_duration = ( len (chunk) / TARGET_SAMPLE_RATE ) logger. info ( f"[Chunk{chunk_index}/{total_chunks}] " f"samples={len(chunk)}, " f"bytes={len(binary)}, " f"duration={chunk_duration:.3f}s" ) # 模拟真实实时发送 await asyncio. sleep (chunk_duration) elapsed = time. time () - start_time logger. success ( f"Audio stream completed (elapsed={elapsed:.2f}s)" ) # ============================================================================= # Main # ============================================================================= async def simulate_frontend_stream ( file_path : str, uri : str,): if not Path (file_path). exists (): logger. error ( f"Audio file not found:{file_path}" ) return # load audio pcmf32 = load_audio (file_path) logger. info (f"Connecting websocket:{uri}") try : async with websockets. connect ( uri, max_size=20 * 1024 * 1024, ping_interval=20, ping_timeout=20,) as websocket : logger. success ("WebSocket connected") # stream audio await stream_audio ( websocket, pcmf32,) # EOS logger. info ("Sending EOS") await websocket. send ("EOS") # wait result logger. info ("Waiting ASR result...") result = await asyncio. wait_for ( websocket. recv (), timeout=30.0,) logger. success ( f"ASR Result:\n{result}" ) except asyncio. TimeoutError : logger. error ( "Timeout waiting ASR result" ) except websockets. ConnectionClosed as e : logger. error ( f"WebSocket closed: " f"code={e.code}, " f"reason={e.reason}" ) except Exception as e : logger. exception ( f"Unexpected error:{e}" ) finally : logger. info ("Test finished") # ============================================================================= # Entry # ============================================================================= if __name__ == "__main__" : asyncio. run ( simulate_frontend_stream ( AUDIO_FILE, WS_URI,) )TTS目前仅支持了 CosyVoice3 模型
Curl 命令:
curl -X POST "http://localhost:7901/hlie/v1/start" \
-H "Content-Type: application/json" \
-d '{ "model_type": "cosyvoice", "model": "HiModel_xh2_cosyvoice3_0.5b_1chip_2cores_v1.1.0-20260409" }'
AI 助手:
curl -X POST "http://localhost:7901/v1/audio/speech" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{ "input": "君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪!人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。岑夫子,丹丘生,将进酒,杯莫停。与君歌一曲,请君为我倾耳听。钟鼓馔玉不足贵,但愿长醉不复醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马、千金裘,呼儿将出换美酒,与尔同销万古愁!", "prompt_wav_path": "E:/test_data/tts/zero_shot_0.wav", "prompt_text": "八百标兵奔北坡,北坡炮兵并排跑,炮兵怕把标兵碰,标兵怕碰炮兵炮。" }'
上述参数其中prompt_wav_path的音频必须与 promt_text的文字一一对齐,当然这两个参数也可以都不需要,如:
下面这种方式,在推理时会使用系统自带的默认的prompt。
curl -X POST "http://localhost:7901/v1/audio/speech" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{ "input": "君不见,黄河之水天上来,奔流到海不复回。君不见,高堂明镜悲白发,朝如青丝暮成雪!人生得意须尽欢,莫使金樽空对月。天生我材必有用,千金散尽还复来。烹羊宰牛且为乐,会须一饮三百杯。岑夫子,丹丘生,将进酒,杯莫停。与君歌一曲,请君为我倾耳听。钟鼓馔玉不足贵,但愿长醉不复醒。古来圣贤皆寂寞,惟有饮者留其名。陈王昔时宴平乐,斗酒十千恣欢谑。主人何为言少钱,径须沽取对君酌。五花马、千金裘,呼儿将出换美酒,与尔同销万古愁!" }'在麒麟(Kylin)系统上安装驱动前,请先关闭系统安全中心,否则驱动将无法安装。
当前调试阶段,HLIECpp.service 会产生 journal 日志。如果想限制日志大小,可以按下面方法设置:
在 /etc/systemd/journald.conf 中设置 SystemMaxUse=500M
使新配置生效:
sudo systemctl daemon-reexec
| 版本 | 日期 | 描述 |
|---|---|---|
| 1.0.0 | 2024年07月10日 | 正式版本 |
| 1.1.0 | 2025年7月25日 |
1. 支持多模态接口。支持使用M30运行qwenvl2.5 7b 3b 模型 2. 支持Qwen3 关闭think能力 3. 减低对libc的版本依赖,支持ubuntu20.04. |
| 1.1.1 | 2025年8月15日 | 1. 支持deepseek qwen3,支持 qwen2.5 Coder 2. 支持双卡14B |
| 1.1.2 | 2025年9月2日 | 更新run_llama-server.sh 的使用 |
| 1.2.0 | 2025年9月29日 | 1. 支持m50 qwen2.5vl 2. 支持多batch模型 3. 升级llama-server, 升级webui |
| 1.3.0 | 2025年11月26日 | 1. 支持统计消息解读 2. 支持启动信息解读 |
| 1.3.2 |
2025年12月28日 | 1. 不兼容之前版本模型 2. 支持llama-server 支持动态加载、卸载模型 3. 支持llama-server 以service方式运行 4. model-cli 工具发布,支持模型下载及本地模型管理能力。 5. 1.3.2 版本文档使用说明HLIELLama 部署及使用指南 |
| 1.4.0 | 2026年02月28日 | 1. 只支持1.0.0 版本模型。 2. 支持cache-prompt。 3. 升级hlaw_ollama 工具。 4. 支持qwen3-vl-30b-a3b模型。 5. 升级hlaw_ollama,支持配置openclaw等 6. 支持llama_decode 接口的abort 回调。 7. 支持带lora_mask 的模型,支持lora动态开关。 8. 1.4.0 版本文档使用说明HLIELLama 部署及使用指南 |
| 2.0.0 |
2026年03月30日 |
1. 升级到1.1.0 2. 支持Qwen3.5 9B, 30B-A3B。 3. hlaw_ollama 升级为定制版本,内置gguf模型下载,支持openclaw自动配置。 4. 支持qwen3-embedding, qwen3-rerank 模型。 5. 1.5.0 版本不再支持M30。 6. reasoning-format 默认为auto 7. 支持think等级设置。 8. llama-gguf 可以查看模型基本信息 。 9. llama-server webui 支持mcp 配置。 10. 2.0.0 版本文档使用说明HLIELLama 部署及使用指南 |
| 2.0.1 | 2026年04月22日 |
1. 修复2.0.0 遗留bug. 修复np>1 乱码问题,修复llama-bench 报错。 2. 升级model_cli 工具,校验下载后的模型完整性。 3. 升级llma-gguf 工具,支持查看gguf 信息。 4. 支持qwen3.5/3.6多模态 5. 支持qwen3 投机解码(cpu+npu) 6. 添加VL 模型使用建议 7. 当前qwen3.5/3.6使用np>1 可能出现NPU内存不够等问题。暂不支持,下个版本优化。 |
| 2.1.0 |
2026年05月09日 |
1. 升级llama到e43431b3811543efdad896e93a992551cc72ab5a支持更多架构模型 2. webui 去掉enable thinking 控制开关和社区保持一致,qwen系列关闭思考使用过-rea off。 3. 基于1.3.0 runtime 4. Gemma4 支持 5. Qwen3.5/3.6 双卡支持 6. Qwen3.5/3.6 MTP 支持 (当前不支持vit) 7. Qwen3-ASR 、GLM-ASR支持 8. Qwen3-ASR-Force-Aligner 9. VIT 支持视频帧接口,qwen系统默认2帧 10. aarch版本的发布组件page align 到64K (完成) 11. GLM-OCR 模型支持 (完成) 12. 支持qwen3 投机解码npu+npu. (完成) 13. 进一步优化性能 |
| 2.1.1(开发中) |
2026年05月18日 |
本HLIELLama 是基于开源llama.cpp集成了的推理逻辑。本文档介绍如果部署定制的llama.cpp.
| M50 |
Qwen3 4B | https://modelscope.cn/models/Qwen/Qwen3-4B-Instruct-2507 |
|---|---|---|
| Qwen3 8B | https://modelscope.cn/models/Qwen/Qwen3-8B | |
| Qwen3 14B | https://www.modelscope.cn/models/Qwen/Qwen3-14B | |
| Qwen3 32B | https://www.modelscope.cn/models/Qwen/Qwen3-32B | |
| Qwen3 VL 4B | https://modelscope.cn/models/Qwen/Qwen3-VL-4B-Instruct | |
| Qwen3 VL 8B | https://modelscope.cn/models/Qwen/Qwen3-VL-8B-Instruct | |
| Qwen2.5 VL 7B | https://modelscope.cn/models/Qwen/Qwen2.5-VL-7B-Instruct | |
| Qwen3 30B A3B | https://www.modelscope.cn/models/Qwen/Qwen3-30B-A3B | |
| Qwen3-2507 30B A3B | https://www.modelscope.cn/models/Qwen/Qwen3-30B-A3B-Instruct-2507 | |
| Qwen 2.5 7B | https://modelscope.cn/models/Qwen/Qwen2.5-7B-Instruct | |
| DeepSeek 8B | https://modelscope.cn/models/deepseek-ai/DeepSeek-R1-0528-Qwen3-8B | |
| bge-m3 | https://www.modelscope.cn/models/BAAI/bge-m3 | |
| gte-qwen2 1.5b | https://www.modelscope.cn/models/iic/gte_Qwen2-1.5B-instruct | |
| Qwen3 coder 30B A3B 32k | https://www.modelscope.cn/models/Qwen/Qwen3-Coder-30B-A3B-Instruct | |
| Qwen3-VL 30B A3B 8k | https://modelscope.cn/models/Qwen/Qwen3-VL-30B-A3B-Instruct | |
| gpt-oss-20b 32k | https://www.modelscope.cn/models/openai-mirror/gpt-oss-20b | |
| Qwen3-Reranker-8B | https://modelscope.cn/models/Qwen/Qwen3-Reranker-8B | |
| Qwen3-Embedding-8B | https://www.modelscope.cn/models/Qwen/Qwen3-Embedding-8B | |
| minicpmo2.6 (支持视觉部分) | https://www.modelscope.cn/models/OpenBMB/MiniCPM-o-2_6 | |
| qwen3.5 2b 4b 9b 27B |
https://modelscope.cn/models/Qwen/Qwen3.5-4B https://modelscope.cn/models/Qwen/Qwen3.5-9B https://modelscope.cn/models/Qwen/Qwen3.5-27B | |
| qwen3.5 35b-a3b | https://www.modelscope.cn/models/Qwen/Qwen3.5-35B-A3B | |
| qwen3.6 35b-a3b | https://modelscope.cn/models/Qwen/Qwen3.6-35B-A3B | |
| gemma4 | https://modelscope.cn/models/google/gemma-4-26B-A4B-it | |
| Cowpaw | https://modelscope.cn/models/AgentScope/CoPaw-Flash-9B |
CPU结构:x86_64/ aarch64
硬盘:200G
AI硬件:M50
操作系统:Ubuntu 20.04
驱动版本:
M50-v1.0.0
推理服务部署包的目录完整结构示例如下。首先确认下载正确的版本, M30和M50 使用不同的压缩包,判断文件名是否有xh1(m30)或者xh2(m50). 可以在零刻AI网站的模型栏目中下载:https://llm.bee-link.cn/。
. ├── bin ├── include ├── lib ├── models ├── scripts ├── service └── version.txt
bin 目录为llama.cpp 自带的一些二进制用于自测, 其中主要的是llama-server。
bin ├──hlaw_ollama//ollama实现,处于实验阶段 ├──llama-bench//bench工具 ├──llama-cli//命令行交互工具 ├──llama-gguf//gguf工具支持rn命令 ├──llama-gguf-split//支持将gguf文件切分为多个gguf文件 ├──llama-server//提供webapi,openai兼容接口 ├──model-cli//model-cli支持简单模型管理
Include 目录为llama.cpp 头文件目录,供基于llama.cpp 进行二次开发
Lib 目录为llama.cpp 生成的库及依赖的库(sdk)
Scripts 为模型打包脚本,用于将模型打包成gguf模型格式。
scripts ├── convert_hm_to_gguf.py // 转换脚本,讲hmm打包成gguf ├── gguf-py // 转换脚本依赖的gguf库 ├── readhmm // 可以查看hmm模型基本信息工具 └── requirements-convert_hm_to_gguf.txt //依赖
如果用户微调的模型,需要最后转成gguf格式进行加载。如果知识评测开源模型,跳过这个步骤。转换脚本在scripts目录下
模型的编译量化参考文档。量化编译后,建议调用hmmstrip工具裁剪掉prefill和decode 共享的权重
工具位置编译容器中/usr/local//bin/hmmstrip,具体使用参考--help 说明。
example:
执行后decode模只有几百兆,用压缩后的decode模型即可,
/usr/local//bin/hmmstrip --strip -o decoder.hmm -i qwen3-prefill.hmm qwen3-decode.hmm
建议python3环境>=3.10, 建议3.10 或者3.12
pip3install-rscripts/requirements-convert_hm_to_gguf.txt
模型的编译量化参考文档。具体文档下载路径见文档中心https://模型资源中心/doc
下载官方配置文件。
如从魔塔社区下载,下载到your_local_dir (和hmm放在同一个文件夹内)
modelscopedownload--modeldeepseek-ai/DeepSeek-R1-0528-Qwen3-8B--exclude '*.safetensors'--local_diryour_local_dir
执行转换操作。(qwen2.5、qwen3 等模型的转换,qwenvl和deepseek转换参考3,4)
python3convert_hm_to_gguf.pyyour_local_dir/
qwen2.5-vl 转换
文本模型转换
# 文本模型指定vit 模型的width & height python3convert_hm_to_gguf.pyyour_local_dir/
视觉模型转换
python3convert_hm_to_gguf.pyyour_local_dir/--mmproj--outfileyour_local_dir/mmproj.gguf
bge-m3/bge-reranker-v2-ms模型转换
需要将hmm文件重命名为embedding.hmm。 其他和上面流程一致。
modelscopedownload--modelBAAI/bge-m3--exclude '*.safetensors'--local_dirbge-m3 # 将hmm文件重命名为embedding.hmm python3convert_hm_to_gguf.pybge-m3
deepseek的转换
当前deepseek-qwen3 转换会报错,
convert_hm_to_gguf.py ", line 1029, in get_vocab_base_pre raise NotImplementedError( NotImplementedError: BPE pre-tokenizer was not recognized - update get_vocab_base_pre()
可以通过如下方式更新tokenizer.json文件来解决。
from transformers import AutoTokenizer * # 替换成你目标模型的正确 HuggingFace 模型名称,比如:* model_name = "deepseek-ai/[DeepSeek-R1-0528-Qwen3-8B](https://huggingface.co/deepseek-ai/DeepSeek-R1-0528-Qwen3-8B)" * # 请确认这个名称是否正确!* * # 下载到本地缓存 ~/.cache/huggingface...* tokenizer = AutoTokenizer. from_pretrained (model_name) # 执行下面命令将*.json 保存到your_local_dir tokenizer. save_pretrained (your_local_dir)
【v1.3.2新增特性】
使用bin目录下面的model-cli进行模型下载,下载的模型为基于开源模型进行量化编译的模型,使用说明如下。
Usage:./model-cli [options]<command> [args] Options: -hoststring TargetserverIP/Host (default "127.0.0.1") -model-pathstring Custommodelsdirectory (overridesenvanddefault) -portint TargetserverPort (default 17701) Commands: query [k=v...]Queryremote (auto-detectstarget,default: open_type=cloud&format=gguf) pull<ids|urls>DownloadbyIDorURL.examplepull 123 124 listList localmodels psListloadedmodels run<name>Loadamodel stop<name>Unloadamodel rm<name>Delete localmodel
支持size\batch\device\target 等过滤。如: target=xh2
CTX: 表示模型最大上下文长度
BATCH: 是否是多batch模型
DEVICE: 表示是单卡模型还是多卡模型。 如2 表示双卡模型,需要跑在DM.2或者多芯PCIE卡上.
FILES: 表示几个gguf文件,通常多模型模型为2个。
BUILD: 表示模型使用哪个版本的工具链编译的。
user@user-System-Product-Name:~/dev/tools$./model-cliquery Auto-detectedtarget:xh2 Fetchingfrom:https://llm.bee-link.cn//models?build_version=1.0.0&format=gguf&open_type=cloud&target=xh2 Found 23models: IDNAMESIZEBUILDCTXBATCHDEVICETARGETCORESFILES ---------------------------------------------- 1767880490946qwen3-vl4b 1.0.0 16384 1 1xh2 2 2 1767880490947qwen314b 1.0.0 32768 1 2xh2 2 1 1767880490948qwen332b 1.0.0 32768 1 4xh2 2 1 1767880490949qwen2.57b 1.0.0 8192 1 1xh2 2 1 1767880490950qwen2.57b 1.0.0 32768 1 1xh2 2 1 1767880490951deepseek8b 1.0.0 32768 1 1xh2 2 1 1767880490952gpt20b 1.0.0 65536 1 1xh2 2 1 1767880490955gte 1.5b 1.0.0 2048 1 1xh2 2 1 1767880490956bge 0.5b 1.0.0 32768 1 1xh2 2 1 1767880490957bge-reranker-v2-m3 0.5b 1.0.0 32768 1 1xh2 2 1 1767880490958qwen34b 1.0.0 32768 1 1xh2 2 1 1767880490959qwen38b 1.0.0 32768 1 1xh2 2 1 1767880490960qwen38b 1.0.0 16384 4 1xh2 2 1 1767880490961qwen314b 1.0.0 16384 1 1xh2 2 1 1767880490962qwen3-vl4b 1.0.0 32768 1 1xh2 2 2 1767880490963qwen3-vl8b 1.0.0 32768 1 1xh2 2 2 1767880490964qwen2.5-vl7b 1.0.0 8192 1 1xh2 2 2 1767880490965qwen330b-a3b 1.0.0 32768 1 1xh2 2 1 1767880490966qwen3-vl30b-a3b 1.0.0 8192 1 1xh2 2 2 1772188146032qwen3-250730b-a3b 1.0.0 32768 1 1xh2 2 1 1772188325612qwen3-250730b-a3b 1.0.0 32768 1 2xh2 2 1 1772799664016gpt20b 1.0.0 65536 1 2xh2 2 1 1772878235701gpt20b 1.0.0 131072 1 1xh2 2 1 Todownload:./model-clipull<ID>
模型模型下载默认路径为:相对model-cli 的路径,../models目录
亦可以通过--model-path 执行下载路径。
【需要llama-server以--models-dir 方式启动】
list 列出已经加载的模型
run:加载一个模型
加载需要时间,实际返回表示已经接收到加载命令,通过ps查看加载结果。
ps: 查看已经加载的模型
stop: 为卸载一个已经加载的模型
注意:
建议直接运行llama-server,亦支持安装后以后台服务方式运行。新版本不再建议使用run_llama-server.sh 脚本,后续版本会移除run_llama-server.sh
长稳测试建议加上--cache-ram 0,否则会缓存每次会话的prompt 导致内存缓慢增长,最大缓存8G。下个版本默认关闭该特性。
# 首先进到压缩包目录 cd-application-software-llama.cpp-xh2 # 查看支持的命令 ./bin/llama-server--help
启动时候指定模型,预先加载模型进行测试。
# model_name 为gguf模型文件绝对路径 ./bin/llama-server-mmodel_name.gguf # 加载多模态 ./bin/llama-server-mmodel_name.gguf--mmprojmmproj.gguf
启动时候不加载模型,指定模型存放目录,根据用户需求动态加载模型。显存足够情况下可以同时加载多个模型。当前版本不支持动态更新模型列表,只会启动时候遍历--models-dir 指定的目录。
动态加载,每次请求需要携带正确的模型名。
./bin/llama-server--models-dirmodels
可以使用bin/model-cli 工具进行模型加载、卸载操作。
./bin/model-clilist # 列出llama-server 启动时扫描到的模型 ./bin/model-clirunmodelname # 加载模型 ./bin/model-clistopmodelname # 卸载模型
可以通过webui 动态的加载卸载模型
通过webapi 进行加载卸载
/models/load
{model: "qwen3-vl_4b_32769_1_1"} /models/unload
{model: "qwen3-vl_4b_32769_1_1"}第一次请求的加载,请求中model要是指定正确值。
在service 目录存在install_llama-server.sh & uninstall_llama-server.sh 脚本。
执行llama-server即以”动态加载模型“(2.5.1.2 )描述的方式以后台服务方式运行,通过model-cli 或者ui界面动态进行模型加载卸载。
# 安装指令 sudobashservice/install_llama-server.sh # 服务管理 sudosystemctlstatusllama-server.service # 查看服务状态 sudosystemctlstartllama-server.service # 启动服务 sudosystemctlstopllama-server.service # 停止服务 sudosystemctlrestartllama-server.service # 重启服务 sudojournalctl-ullama-server.service-f # 实时查看服务日志 # 服务卸载 sudobashservice/uninstall_llama-server.sh
具体的使用参数参考llama-server二进制文件,如果想同时支持并发访问,可以--np 4 (当前限制最大为4,只有多batch模型是真正的并发,单batch的模型是交替执行)
./bin/llama-server--models-dirmodles
Embedding 模型运行的参数和LLM vLLM 略有不同。以gte为例
当前需要-b -ub 大于等于context_length。【v2.0.1 会根据上下文自动调整-b -ub 参数的默认值】
./bin/llama-server-m../models/gte_Qwen2-1.5B-Q4_0.gguf--embedding--poolinglast-b 8096-ub 8096
./bin/llama-server-m../models/Qwen3-Reranker-8B-Q4_0.gguf--rerank
单卡模型默认跑在DEVICE_ID 0, 多卡模型默认跑在DEVICE_ID 0,1。
drv_DEVICE_ID 优先级最高
export drv_DEVICE_ID=0或者双卡export drv_DEVICE_ID=0,1
--list-devices 列出卡的状态
--device 0 表示跑在卡0
user@user-System-Product-Name:~$./dev/llama.cpp/release/xh2/x86_64/bin/llama-server--list-devices [NPU]LoadingNPUSDK... [NPU]Tryingtoload:/usr/local/-sdk/hal/lib/libhal_xh2a.so [NPU]Successfullyloaded:/usr/local/-sdk/hal/lib/libhal_xh2a.so [NPU]hm_sys_get_device_inforeturned: 1devices [NPU]Device 0: device_id=0 [NPU]get_mem_inforeturned: 0, mem_total=24448, mem_used=0, mem_avail=24448 [NPU]Finaldevicememory: total=24448MB, free=24448MB [NPU]Initializationcomplete, 1devicesavailable Availabledevices: 0:NPULQ50 (ID: 0) (24448MiB, 24448MiBfree)
./bin/llama-server-mmodel_name--port 18080
./bin/llama-server-mmodel_name--reasoning-budget 0【2.1.0之前接口】 ./bin/llama-server-mmodel_name-reaoff【2.1.0版本接口,qwen3.5等需要使用这个参数】
备注:以上推理端关闭Think后,实际Think是否生效由应用端请求参数控制,具体见2.5.2.9
./bin/llama-server-mmodel_name--jinja--chat-template-filebin/qwen3_nonthinking.jinja
--log-file写日志到文件 --log-timestamps为打印uptime的时间, --verbosity控制等级 - 0:genericoutput - 1:error - 2:warning - 3:info - 4:debug example --log-file/home/useradmin/test.log--log-prefix--log-timestamps--verbosity 2
请求体中
{
"temperature" : 0.8,
"top_p" : 0.9,
"repetition_penalty" : 1.1,
"chat_template_kwargs" : {"enable_thinking" : false}
}如果设置为none 表示关闭think, 如gpt-oss 支持设置low, medium, high 等级。
{
"temperature" : 0.8,
"top_p" : 0.9,
"repetition_penalty" : 1.1,
"reasoning" :{"effort" : "low"}
}设置别名后模型名比较简洁
-a,--aliasSTRING set alias formodelname (tobeusedbyRESTAPI)
针对大模型推理,复用kv cache, 降低TTFT时间。
多轮对话,每次携带历史记录,避免历史记录重新送模型推理,复用之前计算好的kv cache.
长system prompt场景
当系统内存比较小的场景,直接加载容易OutOfMemory。需要启动参数加上 --no-mmap, 设置后会使得加载过程变慢,请知悉。
qwen3.5/3.6 的cache_prompt 的实现,会占用一些NPU或者HOST内存.
单卡模型保存最多40组缓存,默认保存在NPU上(占用1G+)。
双卡模型保存最多80组缓存,默认保存在Host上,当前只支持Host (占用2G+)。
可以通过环境变量修改占用位置及大小。
export LLAMA_CHECKPOINT_STORAGE=1 #表示存在device上,0 表示host上 #日志信息:set checkpoint_storage_ to kDevice from env LLAMA_CHECKPOINT_STORAGE export LLAMA_CHECKPOINT_INTERVAL=1024 #表示每隔多少个tokens 保存一次,默认1024, 最大40960
reasoning-format=none,表示think 部分放在"message.content" 字段
reasoning-format=auto , think部分放在"message.reasoning_content" 字段。
新的应用都能兼容reasoning_content 格式,不建议修改默认设置,当前默认设置为auto gpt-oss 模型加上--reasoning-format auto, 否则不会解析输出消息格式。
--spec-type draft-mtp --spec-draft-n-max 4
2.1.0 只支持文本部分,不带视觉部分。
./bin/llama-server-m~/dev/models/HiModel_xh2_qwen3.6_27b_mtp_256_128k_1chip_2cores_v1.3.0_20260603.gguf--spec-typedraft-mtp--spec-draft-n-max 4
HTTP推理
curl-XPOST "http://127.0.0.1:17701/v1/audio/transcriptions" \ -H "Content-Type: multipart/form-data" \ -F"model=Qwen3-ASR" \ -F"file=@E:/test_data/audio/test.wav"
HTTP推理
curl-XPOST "http://127.0.0.1:17701/v1/audio/transcriptions" \ -F"file=@E:/test_data/audio/test.wav;type=audio/wav" \ -F"model=Qwen3-ForcedAligner-0.6B" \ -F"response_format=json" \ -F"asr_force_align=true" \ -F"text=HE BEGAN A CONFUSED COMPLAINT AGAINST THE WIZARD WHO HAD VANISHED BEHIND THE CURTAIN ON THE LEFT" \ -F"language=English"
这里的参数需要注意:
text 参数需要与音频一一对应;
language 参数需要匹配对应的此音频的主语言。
| n_ctx_length | 模型支持的最大上下文长度 |
|---|---|
| n_layer | 模型层数(模型相关) |
| n_embd | 模型embed的长度 |
| model_desc | 模型描述,Q4_0 因大模型主要是w4a8 量化,故展示为Q4_0 |
| allow_image | 是否支持图片输入 |
| allow_audio | 是否支持语音输入 |
| vision-width 、vision-height | 图片resize后分辨率 |
| VmPeak | 虚拟内存使用峰值 |
| VmSize | 启动后虚拟内存占用 |
| VmHWM | 物理内存使用峰值 |
| VmRSS | 加载后物理内存占用 |
Llama-server 信息默认开启了cache-prompt, 故prefill的tokens 数是剔除了前缀部分的。使用--no-cache-prompt 看到的信息更容易理解。
下图为VL模型的展示系统.
| Image eval time | 表示vision模型耗时154ms, 每幅图片编码为196toknes |
|---|---|
| Prefill eval time | 表示prefill模型耗时,共处理209tokens(包含图片的196tokens) |
| Decoder eval time | 表示decode 的耗时 |
| Total eval time | 表示端到端的延时 |
| TTFT | 首字延迟(vision+prefill) |
| TOPT | 每个token 间隔 |
| E2E Latency | 端到端延时 |
| E2E TPS | 总体吞吐 |
浏览器访问http://ip:17701 即可,IP为部署主机的IP,如果本机访问127.0.0.1即可。17701 为默认端口。
统计消息说明:
Context:194/65536 表示这个模型最大上下文为65536 ,已经使用194 tokens
Output: 124 表示本次请求输出101 个tokens
28.1 t/s 表示当前请求deocde的平均速度
点击红色箭头,展示的统计数据
70表示送模型prompt的tokens数量
0.3s 表示首字延迟,当前只展示一位小数。
277.32tokens/s 表示prefill 速度
在设置,MCP配置页面可以配置MCP Server. 如下配置了一个公开的GitMCP 和一个自定义的local-file-mcp-server.
使用chatbox,hichat,dify等工具可以通过openai访问。配置方式参考下图。
启动参数需要加上-np 2 (最大4)多用户时
llama.cpp 发布包,发布多个工具,除了model-cli还包括hlaw_ollama, llama-cli, llama-gguf-split 等工具,工具主要处于实验阶段,可能存在一些问题。
该工具为定制版本ollma,可以使用service目录的install 脚本将安装为service方式运行。具体使用方式参考HLAWOllama 部署及使用。该工具只作为Demo使用。
llama-gguf xx.gguf r 类似于gguf-dump能力
该工具可以从定制模型中切分出prefill.hmm &decoder.hmm,目前只支持qwenvl等pd分类模型。配合工具链发布的readhmm工具可以读取模型信息。本工具主要用于模型追溯,问题定位。
其次可以基于该工具,基于编译后的模型,无需转换gguf,可快速测试验证不同上下文的模型。以qwen3_8b 模型为例,切分后的模型分为三个部分:
qwen3_8b_00001-of-00003.gguf,这个gguf中包含vocab+embedding
qwen3_8b_00002-of-00003.gguf,这个gguf为prefill.hmm
qwen3_8b_00003-of-00003.gguf,这个gguf为decoder.hmm
编译不同上下文的模型,vocab+embedding是共享的,变化的是后面两个,只需要将prefill和decode模型分别覆盖00002 和00003即可。加载模型只需要-m 指定qwen3_8b_00001-of-00003.gguf 这个即可.
命令行版本,基本功能同开源版本。
使用VL模型先阅读这部分内容。
当前VIT模型只支持固定分辨率的,假如:默认提供448*448分辨率,故送给llama-server的图片都会被resize。resize成448*448. 建议调用openai 兼容接口时,调用方完成resize 操作,这样有两个优点:
减少http调用传输开销
llama.cpp 中默认是cpu执行的resize,可能不是最高效的。
当前llama 中的resize 逻辑为等比例压缩再pad,贴到左上角,剩余补(114,114,114),针对检查框类任务,给出的框是针对resize之后的图片,需要自行换算回去。其次做目标检测返回的bbox 通常是0~1 之间或者0~1000分辨率。
24G卡跑qwen3.5 35B-A3B 支持吃np=1
建议qwen3.5 类模型启动参数加上--presence_penalty 1.5
官方建议如下:
| Qwen/Qwen3.5-35B-A3B |
|
|---|---|
| Qwen/Qwen3.5-4B |
| 版本信息 | 文档日期 | 变更说明 |
|---|---|---|
| 1.4.0-Preview | 20260527 | 关键特性及变更说明: 1)vllm基线版本升级到v0.21.0rc1 社区vllm commitid: 18f6bf5a214fd51d0cb08fcf1b59edc5629e7c19 2) 新增gemma4 (含vl模型)的支持 3)新增copawflash 9B支持 4)新增qwen3 draft model投机解码支持 5)新增qwen3.5 mtp投机解码支持 6)新增qwen3 asr 、forcealigner等语音模型 7)支持docker部署,提供dockerfile 8)因许可风险, 不对外提供anaconda下载,请从anaconda官网或其他公网地址下载 9)优化qwen3.5 推理链路 10)新增qwen3-reranker、glm-ocr模型 |
| 1.3.0 | 20260423 | 1)vllm基线版本切换成v0.18.1rc1 2) 新增qwen3.5/qwen3.6 (含448*448 vl模型)的支持 3)新增gpt-oss 20b模型的支持 4)新增qwen3-8b-embedding模型支持 5) 优化多batch相关逻辑 6)promptcache复用修改为按token级别的复用逻辑 7)HLIEvLLM 1.3.0版本,支持qwen3.5 vl系列视觉语言模型,暂不支持qwen3 vl系列相关模型,如需测试qwen3vl相关模型,可下载HLIEvLLM 1.2.0版本体验。 |
| 1.2.0 | 20260327 | 修改内网地址为外网地址 |
| 1.2.0 rc0 | 20260309 | 1)新增TTS和ASR两大功能,对应模型:minicpmo tts和Whisper模型。 2)新增qwen3_vl 30b moe 模型 3) 支持arm linux部署 4) 支持cache prompt的开启和关闭,默认不开启 |
| 历史版本文档 | 版本信息 |
|---|---|
| 1.1.0 release | 20260113 |
| 1.1.0a4 | 20260104 |
| v1.0.0 release | 20251108 |
通过Anaconda安装创建python3.11虚拟环境,不能用miniconda。
首先安装Anaconda:内网测试可从下面网址下载Anaconda安装包:
*linux安装包
x86平台
http://10.10.1.53:8082/artifactory/application_software/open-source/Anaconda3-2025.12-2-Linux-x86_64.sh
ARM64 平台
http://10.10.1.53:8082/artifactory/application_software/open-source/Anaconda3-2025.12-2-Linux-aarch64.sh
下载后执行下面的命令安装Anaconda3
sudochmod 777Anaconda3--Linux-x86_64.sh ./Anaconda3--Linux-x86_64.sh
因许可风险,外部客户请从Anaconda官网或者其他公网下载最新的安装包
Anaconda官方下载网址https://www.anaconda.com/download
用conda创建python3.11虚拟环境:-n 后面指定虚拟环境名
condacreate-nvllm_env python=3.11-y
激活虚拟环境:
condaactivatevllm_env
确保host主机已安装对应版本m50的驱动,且hm_smi输出正常。
在零刻AI网站推理框架栏目下载 HLIEvLLM 发布的两个包(https://llm.bee-link.cn/frameworks.php):
HLIEvLLM-1.zip 和 hlievllmplugin-1.-py3-none-any.whl 两个文件
未安装 tcim_runtime 的,请从以下链接下载对应版本的 runtime(注意选择与驱动匹配的版本):https://dr.bee-link.cn/download/dXBsb2Fkcy9MTE0vUnVudGltZS1TREsvaG91bW9fdGNpbV9ydW50aW1lX3hoMl9saW51eF94ODZfNjQtMV80XzBfdGFyLmd6/h/ca681089f70cbf5962aedfd56d866ba1按照下面步骤安装运行时tcim runtime v1.x?包,同时注意推理卡上的固件版本跟驱动版本要匹配(如果已经安装过运行时-且推理卡上的固件版本确认匹配,此步可跳过)
首先进入到上面创建的python虚拟环境,确保操作系统安装了gcc 、g++,且版本支持C++11,否则运行时tcim runtime会安装失败
没安装的话执行下面的命令安装:
sudoaptinstallg++
然后执行下面的命令安装tcim runtime包:
Linux系统:注意根据cpu架构,选择对应版本 x86平台: 1.3.0的runtime包 pipinstallhttp://10.10.1.53:8082/artifactory/drv_software/release_xh2_v1.3.0/2026/05/19/0015/ubuntu2004/drv_tcim_runtime_xh2_linux_x86_64-1.3.0.tar.gz-ihttps://mirrors.aliyun.com/pypi/simple/ arm平台: 1.3.0的runtime包 pipinstalldrv_tcim_runtime_xh2_linux_aarch64-1..0.tar.gz-ihttps://mirrors.aliyun.com/pypi/simple/
注意:需要先安装HLIEvLLM,再安装HLIEvLLMPlugin.这步会安装HLIEvLLM依赖的软件包,需要点时间。正常10-20分钟左右能安装完。
a.Linux系统安装HLIEvLLM
HLIEvLLM从1.3.0版本开始,优先使用vllm官方建议的tcmalloc-minimal和omp库,按照官方说明,要先安装下面几个依赖项:
依赖项1: sudoapt-getinstalllibnuma-dev 依赖项2: sudoapt-getinstall-y--no-install-recommendslibtcmalloc-minimal4 sudofind/usr-namelibtcmalloc_minimal*so 返回的路径要用到下面的环境变量设置中 依赖项3: sudoapt-getinstalllibomp5libomp-dev sudofind/usr-namelibomp*so* 设置下面的环境变量,以便找到相关的库 export IOMP_PATH=/上面findomp命令返回的路径/libomp.so.5 export TC_PATH=/上面findtcmalloc命令返回的路径/libtcmalloc_minimal.so.4 export LD_PRELOAD="$TC_PATH:$IOMP_PATH:$LD_PRELOAD" echo $LD_PRELOAD x86平台LD_PRELOAD变量输出示例如下: /usr/lib/x86_64-linux-gnu/libtcmalloc_minimal.so.4:/usr/lib/x86_64-linux-gnu/libomp.so.5: arm平台LD_PRELOAD变量输出示例如下: /usr/lib/aarch64-linux-gnu/libtcmalloc_minimal.so.4:/usr/lib/aarch64-linux-gnu/libomp.so.5:
b.下载vllm 版本
解压压缩包,进到解压后的文件夹,如“HLIEvLLM-1.3.0”,执行下面的命令安装vllm(因为要下载依赖项,预计10分钟左右可以安装完):
Ubuntu 22.04 及以下的ubuntu系统,默认 gcc 版本低于 12.3,需要升级gcc版本,否则vllm编译报错,按下面方法升级(gcc 版本大于等于 12.3 可以不用升级):
# 1. 添加官方源(针对 Ubuntu 20.04/22.04) sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt update # 2. 安装 gcc-13 和 g++-13,如果下载较慢,ctrl—c终止,然后重新下载试试,速度不低于200KB/s就行。速度如果一直较慢,请设置clash 翻墙代理,正常不到10分钟可以安装完成 sudo apt install -y gcc-13 g++-13 # 3. 设置为系统默认版本(关键) sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100 # 4. 验证版本(输出应为 13.+) gcc --version g++ --version
先确认gcc和g++ 版本大于等于12.3,然后进到解压后的文件夹,如“HLIEvLLM-1.3.0”执行下面的命令安装版本vllm:v1.4.0preview版本安装完记得把fastapi 版本降级到0.136.3或者0.136.1,正式版会修复此问题,preview发版后发现fastapi版本升级了,最新版fastapi不兼容。参考第3章的3.1说明
VLLM_TARGET_DEVICE=cpupipinstall-e.--extra-index-urlhttps://download.pytorch.org/whl/cpu-ihttps://mirrors.aliyun.com/pypi/simple/
如果需要运行audio相关模型,比如下面的Whisper模型,请安装额外的依赖项,进到解压后的文件夹,如“HLIEvLLM-1.3.0”执行下面的命令安装:
VLLM_TARGET_DEVICE=cpupipinstall-e ".[audio]"--extra-index-urlhttps://download.pytorch.org/whl/cpu-ihttps://mirrors.aliyun.com/pypi/simple/
注意:如果安装了老版本的whl插件包,务必先卸载老的包,执行命令pip uninstall HLIEvLLMPlugin 进行卸载。
如果安装过程中,遇到 unsupported instruction vpdpbusd'报错信息,请先设置下面的两个环境变量,再安装:
export CFLAGS="-mno-avx"
export CXXFLAGS="-mno-avx"
whl包安装命令如下:
VLLM_TARGET_DEVICE=pipinstallhlievllmplugin-1.-py3-none-any.whl--no-build-isolation--extra-index-urlhttps://download.pytorch.org/whl/cpu-ihttps://mirrors.aliyun.com/pypi/simple/
安装完成后,通过下面命令输出中的 Location: 值,查看安装位置和源码路径:
pip show HLIEvLLMPlugin
示例路径:/home/useradmin/anaconda3/envs/vllm_env_120rc0/lib/python3.11/site-packages/vllm_/
# 解压安装包并进入目录 tarzxvf-Python-xh2_3.0.0_linux_x86_64.tar.gz cd-Python-xh2_3.0.0_linux_x86_64 # 执行初始化脚本加载镜像 bashinit.sh # 将GGUF 模型以目录格式存放到 models/ 目录,例如: mkdirmodels/Qwen3.5_35B wget-Pmodels/Qwen3.5_35Bhttp://xxx/Qwen3.5_35B.gguf # 修改docker-compose.hlievllm.yaml 中的启动命令 vimdocker-compose.hlievllm.yaml # 启动 hliepython 服务 dockercompose-fscripts/docker-compose.hlievllm.yamlup-d # 查看服务启动日志 dockercompose-fscripts/docker-compose.hlievllm.yamllogs--tail 100-fhlievllm # 下线 hliepython 服务 dockercompose-fscripts/docker-compose.hlievllm.yamldown
【注意】
docker-compose.hlievllm.yaml 中启动命令字段中的模型目录应该使用容器中挂载的模型目录,默认挂载到容器的目录为/opt/hlievllm/models。
测试前请阅读下面a)-->h)的几点说明:
a) HLIEvLLM 为了调试定位问题,代码中有很多info信息,如果是调试定位问题,可以把日志级别设低;如果是性能模式,可以关闭info。下面是具体的方法,设置1个环境变量就行
性能模式(默认模式):减少debug输出,decode输出速率更快,VLLM_LOGGING_LEVEL设置为下面的值:
export VLLM_LOGGING_LEVEL=WARNING
调试Debug模式:VLLM_LOGGING_LEVEL设为下面的值,会打印很多日志
export VLLM_LOGGING_LEVEL=DEBUG
b)关键路径的耗时统计和打印:
此版本代码包含了vllm推理流程中关键路径的统计耗时,用于性能分析,默认不开启不执行。如需查看相关耗时统计,请设置下面的环境变量,耗时统计不受VLLM_LOGGING_LEVEL控制:
export ENABLE_TIMING=1
c) HLIEvLLM 此版本对应的gguf模型文件,外网下载链接:
https://llm.bee-link.cn//,版本那一栏请选择1.2.0版本对应的模型。
注意: qwen3.5/qwen3.6 35B MOE模型,版本那一栏请选择1.3.0或1.4.0版本对应的模型,或者咨询FAE同事获取相关模型版本
如果打不开,请联系FAE同事。
d) 启动推理测试的时候,如果报错:ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6: version `CXXABI_1.3.15' not found
解决方法:修改LD_LIBRARY_PATH环境变量,优先加载conda的libstdc++
定位问题:执行命令 "strings /lib/x86_64-linux-gnu/libstdc++.so.6 | grep CXXABI" .如果没有输出1.3.15,说明系统自带的libstdc++版本低了,需要用conda 自身的libstdc++.so.6。设置变量值如下(修改为自己的conda 虚拟环境对应的目录):
export LD_LIBRARY_PATH=/home/useradmin/anaconda3/envs/vllm_env/lib:$LD_LIBRARY_PATH
e)如需降低cpu利用率: 设置下面的环境变量值,cpu利用率可以有比较明显的降低,但注意decode速率也会降低,请折中选择
export OMP_NUM_THREADS=1
原因:预处理用到了torchvision ,如果不设置这个环境变量的话torch不会限制单个实例的thread数量,会造成cpu利用率升高
f) 如果跑的是多卡的模型,启动vllm的时候,记得加下面的参数,指定在对应的卡上加载模型
--additional-config='{"device_ids":[0,1]}'
g) hlievllm从1.3.0版本开始,默认按照官方建议,启用libtcmalloc_minimal.so.4,运行下面的测试前,请确保对应终端的env变量中,LD_PRELOAD 这个变量值,包含了tcmalloc-minimal和omp库的路径,本文档的1.2小节有相关说明以及设置方法。
h) vllm 启动参数较多,可参考 http://docs.vllm.ai/en/latest/cli/ 或者 https://www.psvmc.cn/article/2026-03-10-ai-vllm-prop.html网站,了解相关参数的含义
测试代码在解压后的 HLIEvLLM-1.*/drv_examples/ 文件夹中:
把测试代码中的模型文件夹,修改成自己下载模型的文件夹。注意:指定的模型文件夹下面只能有 1 个 HiModel 开头的 gguf 文件。不同的 HiModel*.gguf 文件请放到不同的文件夹中。
需要修改测试代码 LLM_*.py 文件中的 “model_name” 变量,指向自己下载的 gguf 文件所在的文件夹。
对于vl模型:还需要修改
additional_config={"visual_model_path": 指向自己的 mmproj*.gguf 文件的绝对路径}
(vllm_env_szj_v110a4)user@PC:/HLIEvLLM-1.*.* $**python3drv_examples/LLM_example_chat.py
(vllm_env_szj_v110a4)user@PC:~/szj_project/HLIEvLLM-1.*.*$python3drv_examples/LLM_qwen35_vl_example.py
使用以下命令执行Qwen3-ForcedAligner-0.6B 模型进行语音和文本的对齐,属于每个文本token 对应语音的时间段。其中,参考文本可以通过语音模型来获取。
【注】需要在hlievllm 环境安装qwen-asr库使用,qwen-asr库会导致transformers 版本降级到4.57.6,使用示例后请手动将transformers 库进行升级避免影响其他模型使用
pythondrv_examples/qwen3_forcealigner_offline.py--model-dir/path/to/Qwen3-ForcedAligner-0.6B--audio/path/to/test.mp3--text "参考文本"--pretty
启动测试前,请再次阅读并注意以下几点:
*)对于多卡模型或者需要指定在某个卡上运行的模型,启动vllm在线推理的时候,加下面的参数指定跑在哪些卡上,下面--additional-config示例是运行双芯模型的示例,表示某个模型要跑在2张推理卡上,卡的id是0和1, 对应的模型需要是双卡模型才行
--additional-config='{"device_ids":[0,1]}'
*)不同类别的模型的tool-call-parser不一样,请参考示例中的进行设置,如更改为其他parser,请确保您了解相关parser而且确定该parser的性能优于推荐的配置
*)vllm默认不开启prompt cache的复用,如需开启,启动vllm的时候加下面的参数:
--additional-config='{"enable_cacheprompt":"True"}'
*) vllm 启动参数较多,可参考 http://docs.vllm.ai/en/latest/cli/ 或者https://www.psvmc.cn/article/2026-03-10-ai-vllm-prop.html 了解相关参数的含义
启动openaiserver 带apikey
以qwen3.5 35B A3B 256K上下文模型 为例:--max-num-batched-tokens 和 --max-model-len 要设置为模型最大上下文长度,--max-num-seqs 要设置为模型实际支持的batch数,如需关闭思维链,在vllm启动的时候加上 --default-chat-template-kwargs '{"enable_thinking": false}' 就行
vllmserve/home/user/szj_project/models/v1.2.0/qwen3.5_35B_a3b/--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen35--max-num-batched-tokens 262144--max-num-seqs 1--max-model-len 262144--enable-auto-tool-choice--tool-call-parserqwen3_coder--additional-config='{"device_ids":[0]}'启动命令:以qwen3 30b a3b 32K上下文为例: 注意toolparser 跟qwen3.5不一样:
vllmserve/home/user/szj_project/models/qwen3_30b_a3b_v1.2.0--port 12321--host 0.0.0.0--no-enable-prefix-caching--max-num-seqs 1--served-model-nameqwen3_30b_a3b--enable-auto-tool-choice--tool-call-parserhermes--max-num-batched-tokens 32768--max-model-len 32768
注意max-num-seqs的值,要跟模型实际的batch匹配。
vllmserve/home/user/szj_project/models/v1.2.0/qwen3_8b_16k_4batch--port 12321--host 0.0.0.0--no-enable-prefix-caching--max-num-seqs 4--served-model-nameqwen3_8b_b4--enable-auto-tool-choice--tool-call-parserhermes--max-num-batched-tokens 16384--max-model-len 16384
启动命令如下:
vllmserve/home/user/szj_project/models/v1.2.0/deepseek_8b--port 12321--host 0.0.0.0--no-enable-prefix-caching--max-num-seqs 1--served-model-namedeepseek_8b--enable-auto-tool-choice--tool-call-parserhermes--max-num-batched-tokens 32768--max-model-len 32768
M50 24G卡支持qwen3.5 /qwen3.6 35B-A3B 视觉语言模型
注意:visual_model_path 跟语言模型不是同一个gguf文件,一般命名为mmproj开头,该文件路径不能用相对路径或者工作目录~ 符号,请用完整的绝对路径,如下面所示:
a)单chip模型启动示例:
vllmserve/home/user/szj_project/models/v1.3.0/qwen35_35b_a3b/--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen35_vl--max-num-batched-tokens 262144--max-num-seqs 1--max-model-len 262144--enable-auto-tool-choice--tool-call-parserqwen3_coder--additional-config='{"enable_cacheprompt":"False","visual_model_path":"/home/user/szj_project/models/v1.3.0/qwen35_35b_a3b/mmproj-qwen3.5-35b-a3b-p256-256K-b1-2core-1d-xh2-v1.3.0-20260420210756.gguf"}' b)多chip模型启动示例-以4chip语言模型+1chip视觉模型启动为例:
vllmserve/home/lenovo/release/models/130/qwen3.6_27b_128k_4chip--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen36_vl--max-num-batched-tokens 131072--max-num-seqs 1--max-model-len 131072--enable-auto-tool-choice--tool-call-parserqwen3_coder--additional-config='{"enable_cacheprompt":"True","visual_model_path":"/home/lenovo/release/models/130/qwen3.6_27b_128k_4chip/mmproj_xh2_qwen3.6_27b_2cores_vit_448x448_v1.3.0_20260603.gguf","device_ids":[0,1,2,3],"vl_device_ids":[3]}' 其中:
"device_ids": [0,1,2,3],指定语言模型跑在哪些卡上,示例是4chip语言模型,跑在devid 0/1/2/3这4张卡
"vl_device_ids": [3],指定视觉模型跑在哪些卡上,示例是1chipvit模型,跑在devid 3这张卡上
注意:卡的数量,要跟模型实际chip数一致。
测试的话可以通过chatbox附上图片进行测试或者用curl命令,示例如下,其中“url”要换成自己本地的图片或者对应的base64数据,“model”名字和密钥要换成自己设置的值,注意最后的EOF要带上。
curl-XPOST [http://127.0.0.1:12321/v1/chat/completions](http://127.0.0.1:7801/v1/chat/completions)-H "Authorization: Bearer sk-123"-H "Content-Type: application/json"-d@- <<EOF
{
"model": "qwen35_vl",
"messages": [
{"role": "system", "content": "你是一个智能助理"},
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,$(base64 -w 0 /home/user/szj_project/-examples-xh2/models/llm/qwen3.5/image_dir/frame85.jpg)"
},
"detail":"high"
},
{
"type": "text",
"text": "请描述图片内容。"
}
]
}
],
"stream": true
}
EOF启动命令:分单芯和多芯模型,
注意:如需开启thinking模式,启动时候要参数,参考下面的示例
单芯模型启动示例:
vllmserve/home/user/szj_project/models/v1.4.0/gemmar4/gemma-4-26B-A4B-it--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-namegemma4--max-num-batched-tokens 32768--max-num-seqs 1--max-model-len 32768--enable-auto-tool-choice--tool-call-parsergemma4--additional-config='{"enable_cacheprompt":"False","visual_model_path":"/home/user/szj_project/models/v1.4.0/gemmar4/gemma-4-26B-A4B-it/gemma-mmproj.gguf","device_ids":[0]}' 多芯模型启动示例:语言模型双芯,vit视觉模型单芯
vllmserve/home/user/vllm_v140_release_teset/models/gemma4_mutlichip/--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-namegemma4--max-num-batched-tokens 32768--max-num-seqs 1--max-model-len 32768--enable-auto-tool-choice--tool-call-parsergemma4--additional-config='{"enable_cacheprompt":"True","visual_model_path":"/home/user/vllm_v140_release_teset/models/gemma4_mutlichip/mmproj_xh2_gemma4-26b-a4b_2cores_vit_448x448_v1.4.0_20260609.gguf","device_ids":[0,1],"vl_device_ids":[3]}' 开启Thinking模式
vllmserve/home/user/szj_project/models/v1.4.0/gemmar4/gemma-4-26B-A4B-it--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-namegemma4--max-num-batched-tokens 32768--max-num-seqs 1--max-model-len 32768--enable-auto-tool-choice--tool-call-parsergemma4--reasoning-parsergemma4--default-chat-template-kwargs '{"enable_thinking": true}'--additional-config='{"enable_cacheprompt":"False","visual_model_path":"/home/user/szj_project/models/v1.4.0/gemmar4/gemma-4-26B-A4B-it/gemma-mmproj.gguf","device_ids":[0]}'--chat-templateexamples/tool_chat_template_gemma4.jinja启动命令:
vllmserve/home/user/szj_project/models/v1.4.0/qwen3_14b_speculate--host 0.0.0.0--port 12321--no-enable-prefix-caching--max-num-seqs 1--served-model-nameqwen3_14b--enable-auto-tool-choice--tool-call-parserhermes--max-num-batched-tokens 32768--max-model-len 32768--additional-config='{"enable_cacheprompt":"True"}'--speculative-config '{"model": "/home/user/szj_project/models/v1.4.0/qwen3_0.6B_speculate", "num_speculative_tokens": 5, "method": "draft_model"}'
说明:
verify主模型: /home/user/szj_project/models/v1.4.0/qwen3_14b_speculate
--speculative-config '{"model": "/home/user/szj_project/models/v1.4.0/qwen3_0.6B_speculate" ,这里指向的是草稿模型的gguf 文件所在的文件夹,文件夹下面只能有1个HiModel开头的gguf文件
启动命令:
vllmserve/home/user/szj_project/models/v1.3.0/qwen35_9b_mtp/gguf_main_verify_model/--max-model-len 262144--speculative-config '{"model":"/home/user/szj_project/models/v1.3.0/qwen35_9b_mtp/gguf_draft_model","method": "mtp", "num_speculative_tokens": 5}'--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen35--max-num-batched-tokens 262144--max-num-seqs 1--max-model-len 262144--enable-auto-tool-choice--tool-call-parserqwen3_codervllmserve/home/user/szj_project/models/v1.3.0/qwen36_27b_mtp--max-model-len 262144--speculative-config '{"model":"/home/user/szj_project/models/v1.3.0/qwen36_27b_mtp","method": "mtp", "num_speculative_tokens": 5}'--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen35--max-num-batched-tokens 262144--max-num-seqs 1--max-model-len 262144--enable-auto-tool-choice--tool-call-parserqwen3_coder启动命令
VLLM_ALLOW_LONG_MAX_MODEL_LEN=1vllmserve/home/user/szj_project/models/v1.0.0/gpt_oss_20b_64K--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-namegpt_oss--max-num-batched-tokens 65536--max-num-seqs 1--max-model-len 65536--enable-auto-tool-choice--tool-call-parseropenai
如果报错:openai_harmony.HarmonyError: error downloading or loading vocab file: failed to download or load vocab file。按照下面的方法解决:(我们自测x86 未遇到此错误,arm上遇到了该错误,gpt-oss需要下面的文件,默认的url可能会下载失败然后报错,按下面方法可以解决)
mkdir-ptiktoken_encodings
curl-L-otiktoken_encodings/o200k_base.tiktoken "https://openaipublic.blob.core.windows.net/encodings/o200k_base.tiktoken"
curl-L-otiktoken_encodings/cl100k_base.tiktoken "https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken"
export TIKTOKEN_ENCODINGS_BASE=${PWD}/tiktoken_encodings| 模型名称 | 支持情况 |
|---|---|
| whisper-medium | 支持 |
| whisper-turbo | 支持 |
| Qwen3-ASR-0.6B | 支持 |
| GLM-ASR-Nano-2512 | 支持 |
vllmserve/path/to/ASR-Model \
--served-model-nameasr-model \
--no-enable-prefix-caching \
--load-formatdummy \
--additional-config='{"visual_model_path": "/path/to/ASR-Model/mmproj-asr-model.gguf"}'
【注】whisper-medium 和 whisper-turbo 模型只有一个主模型,所以不需要--additional-config参数指定额外模型
/v1/audio/transcriptions
curlhttp://127.0.0.1:8000/v1/audio/transcriptions-H "Content-Type: multipart/form-data"-F"file=@test.wav"-F"model=asr-model"-F"language=zh"-F"response_format=json"-F stream=false
启动命令:
vllmserve/home/user/szj_project/models/v1.1.0/qwen3_embedding--port 12321--host 0.0.0.0--no-enable-prefix-caching--served-model-nameqwen3_embed--max-num-batched-tokens 8192--max-num-seqs 1--max-model-len 8192
对应curl测试命令:
curlhttp://127.0.0.1:12321/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-123" \
-d '{"input": "Your text string goes here",
"model":"qwen3_embed"}'服务启动
vllmserve/data/useradmin/models/v1.2.0/qwen3-reranker--served-model-nameqwen3-reranker-8b--max-model-len 8192--host 0.0.0.0--port 7804--api-keysk-123--hf-overrides='{"architectures": ["Qwen3ForSequenceClassification"], "classifier_from_token": ["no", "yes"], "is_original_qwen3_reranker": true}'
/v1/score 请求
# 单个查询对单个文档
curl-X 'POST' 'http://127.0.0.1:7804/v1/score'-H 'accept: application/json'-H 'Content-Type: application/json'-H "Authorization: Bearer sk-123"-d '{
"model": "qwen3-reranker-8b",
"queries": "What is the capital of France?",
"documents": "The capital of France is Paris."
}' # 单个查询对多个文档
curl-X 'POST' 'http://127.0.0.1:7804/score'-H 'accept: application/json'-H 'Content-Type: application/json'-d '{
"model": "qwen3-reranker-8b",
"queries": "What is the capital of France?",
"documents": [
"The capital of Brazil is Brasilia.",
"The capital of France is Paris."
]
}'
/v1/rerank 请求
curl-X 'POST' 'http://127.0.0.1:7804/v1/rerank'-H 'accept: application/json'-H 'Content-Type: application/json'-H "Authorization: Bearer sk-123"-d '{
"model": "qwen3-reranker-8b",
"query": "What is the capital of France?",
"documents": [
"The capital of Brazil is Brasilia.",
"The capital of France is Paris.",
"Horses and cows are both animals"
]
}'| 模型名称 | 支持情况 | 介绍 |
|---|---|---|
| Qwen/Qwen3-ForcedAligner-0.6B | 支持 | Qwen3ASRForcedAlignerForTokenClassification是一个多模态模型,输入类型为 T + A⁺ = 文本 + 音频 |
vllmserve/path/to/Qwen3-ForcedAligner-0.6B \
--served-model-name-model \
--host 0.0.0.0 \
--port 12325 \
--api-keysk-123 \
--runnerpooling \
--enforce-eager \
--hf-overrides '{"architectures": ["Qwen3ASRForcedAlignerForTokenClassification"]}' \
--max-model-len 411 \
--load-formatdummy \
--trust-request-chat-template \
--additional-config '{"visual_model_path": "/path/to/Qwen3-ForcedAligner-0.6B/mmproj-Qwen3-ForcedAligner-Q4_0.gguf"}'PROMPT='参考文本' curl-s-XPOSThttp://localhost:7803/v1/audio/transcriptions \
-H "Authorization: Bearer sk-123" \
-F"file=@/path/to/test.mp3" \
-F"model=asr-model" \
-F"prompt=${PROMPT}" \
-F"language=chinese" \
-F"response_format=verbose_json"启动命令:
vllmserve/home/user/models/glm_ocr--host 0.0.0.0--port 12321--no-enable-prefix-caching--served-model-nameglm-ocr--max-num-batched-tokens 2048--max-num-seqs 1--max-model-len 2048--additional-config '{"visual_model_path":"/home/user/models/glm_ocr/mmproj_xh2_glm-ocr_0.8b_2cores_v1.3.0_20260519.gguf"}'
对应curl测试命令:
curl--location--requestPOST 'http://127.0.0.1:12321/v1/chat/completions'--header 'Content-Type: application/json'--data-raw '{"model":"glm-ocr","messages":[{"role":"user","content":[{"type":"image_url","image_url":{"url":"https://cdn.bigmodel.cn/markdown/1770033643596image.png?attname=image.png"}},{"type":"text","text":"请识别图片中的所有文字。"}]}],"temperature":0,"max_tokens":256}'
本地图片测试命令:
curl-XPOSThttp://127.0.0.1:12321/v1/chat/completions-H "Authorization: Bearer sk-123"-H "Content-Type: application/json"-d@- <<EOF
{
"model": "glm-ocr",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "data:image/jpeg;base64,$(base64 -w 0 /tmp/glm_ocr_test.jpg)"
}
},
{
"type": "text",
"text": "请识别图片中的所有文字。"
}
]
}
]
}
EOFprompt cache复用指缓存模型的输入和输出,当用户的提问携带历史信息时,模型会跳过历史信息重复部分的计算,优化TTFT指标。vllm默认不开启prompt cache的复用,如需开启,参考下面示例-启动vllm的时候加下面的参数:
--additional-config='{"enable_cacheprompt":"True"}'
目前:qwen3 、qwen3.5、qwen3.6、gpt-oss、gemma4 均支持promptcache复用。
启用promptcache复用,可大幅降低长上下文+多轮回话携带历史消息场景下的ttft响应时间,减少不必要的重复计算,请根据使用场景选择。启动 vllm 的时候如果不设置 enable_cacheprompt 或者设置 "enable_cacheprompt":"False",则不开启 promptcache 复用。另外,"True" 或者 "False" 请放到双引号 "" 里面。
参考命令如下:
vllm serve /home/user/szj_project/models/v1.0.0/gpt_oss_20b_64K --port 12321 --host 0.0.0.0 --no-enable-prefix-caching --served-model-name gpt_oss --max-num-batched-tokens 65536 --max-num-seqs 1 --max-model-len 65536 --enable-auto-tool-choice --tool-call-parser openai --additional-config='{"enable_cacheprompt":"True"}'
测试流程如下:
HLChat或者HLChatDeskTop或者chatbox等AI聊天工具中,历史消息数量设置为大于1的值
复制长文本文字 (比如大于2k长度的文本)让大模型总结
查看第一次模型回复的TTFT的时间
再次输入相同的问题,查看大模型TTFT的时间,比第一轮要低很多,不会因为消息数量的增加而导致大模型回复慢很多
可重复多次输入同样的问题,看大模型回复TTFT时间
问一个跟曾经问过大模型的问题相关的内容,看看大模型的回复时间以及回复内容,是否跟历史回复有关,且TTFT值不会大于第一次长文本回复的时间
由于HLIEvLLM v1.4.0 preview开发和测试阶段,fastapi还是0.136.1的版本,测试都正常的。发版后发现 fastapi 最新版升级到了 0.137.x,跟 HLIEvLLM v1.4.0 preview 版本不兼容了。
HLIEvLLM v1.4.0 preview版本跟fastapi最高兼容的版本是:
fastapi 0.136.3
如高于此版本,请降级到0.136.3及以下。0.136.3和0.136.1验证正常。建议用这两个版本。
| 版本 | 日期 | 描述 |
|---|---|---|
| 3.0.1 |
2026年06月16日 | - 支持投机解码 - 更多模型支持,如:Qwen3-ASR、Gamma 4、CoPaw、Qwen3.6/3.5、Qwen3-ForcedAligner |
| 3.0.0 | 2026年04月15日 | - 支持tts模型的推理通道及tts相关接口协议 - 添加语音模型的流式输出的支持(基于WebSocket) - 部署方式支持 whl 包安装 - 支持模型动态加载 |
| 2.8.0 | 2026年03月13日 | - Asr 接口支持,whisper 模型支持 |
| 2.7.0 | 2026年01月05日 | - Embedding接口及推理支持 - 文本、多模态和嵌入模型的推理底层切换到vLLM |
| 2.6.0 | 2025年10月10日 | - 支持gguf 模型 - 减少模型配置,优化应用部署方式 |
| 2.5.0 | 2025年08月06日 | - 添加多模态模型qwen2.5-vl 3b 和 7b 模型的支持,同步/chat/completions 接口的支持 - 优化基础镜像的编译方式,可灵活切换工具链版本 |
| 2.4.0 | 2025年07月02日 | - 优化并修复OpenAI API /chat/completions、/images/generations接口请求和响应参数 - 添加生图模型的支持、添加对qwen3-8b模型的支持,减少对14B模型的支持 - 支持通过config.yaml配置是否加载t5模型到AI卡,以及相关的全局配置参数 |
| 2.3.0 | 2025年05月09日 | - 增加推理服务的部署方式:kubernetes(手动yaml 部署、helm 部署) |
| 2.2.0 |
2025年04月25日 |
- 支持单batch、多batch、14B 模型,新增可支持的模型,如:14B 模型、4batch 模型 - 支持请求服务等待及超时处理 |
| 2.1.0 | 2025年03月14日 |
- 应用部署包和模型部署包解耦,且部署包不区分平台 - 支持的模型增加、优化及更新 - 推理服务增加动态配置参数和非流式重试机制 - 增加健康检查接口、多卡配置、可自定义后端服务模型、端口、设备等配置功能 |
| 2.0.0 | 2025年01月22日 | - 兼容OpenAI 接口部分参数、增加多种模型的支持、增加多项功能支持、解决部分已知问题、多项细节优化 |
| 1.0.0 | 2024年07月10日 | - 正式版本 |
本文档将带你快速连接并启动推理服务,并提供简单的日志排错方式介绍。
当前推理服务的访问主要包含 4 种方式:前端应用系统版本、命令行版本、HTTP 版本 和 OpenAI 版本。可参考以下介绍选择要使用的方式进行访问。
系统前端版本: 当前提供三种应用系统作为前端,在配置相应参数后可基于推理服务提供对外的接口通过浏览器进行访问和操作。这种方式提供了直观的用户界面,适合一般用户,无需掌握技术知识即可与推理服务进行交互。
命令行版本: 在终端界面,通过命令行方式进行交互,适合开发者或技术人员。用户可以通过输入命令发送请求和查看结果,支持调试、HTTP 客户端操作等功能。
HTTP 版本:
提供基于 HTTP 协议的 RESTful API 接口,允许用户通过 HTTP 客户端(如 curl、Postman 等)或集成到其他系统中进行访问。
使用方法:用户需要向指定的服务端地址发送 HTTP 请求,通常包括 POST 或 GET 请求方式,并携带必要的请求体参数(如模型名称、对话内容等)。
适用场景:适合需要通过代码或集成到其他业务系统的场景,具有灵活性高、易于扩展等特点。
OpenAI 版本:
通过兼容 OpenAI 接口的方式访问 ChatBot 系统,允许用户复用现有的 OpenAI 客户端工具(如 openai Python SDK)或基于 OpenAI 标准的第三方应用程序进行交互。
使用方法:用户需配置系统提供的 base_url (和 API 密钥[可选]),以兼容 OpenAI 风格的 SDK 调用方法,例如使用 chat.completions.create() 方法发送请求。
适用场景:适合已有 OpenAI API 使用经验的开发者或想快速上手推理服务的用户,简化上手成本并保持一致的开发体验。
每种服务方式适用于不同的用户群体和应用场景,用户可根据需求选择合适的访问方式。以上提供的四种方式的使用详情,请参考该文档的第四部分《四、系统使用》。
CPU结构:x86_64、aarch64
硬盘:200G
AI硬件:M50
操作系统:Ubuntu 20.04+
驱动版本:
M50-v1.3.0
【注意】
安装本系统前请确保已安装好推理加速卡、并且升级驱动和固件为指定版本
若有启动同类型的大模型推理系统,请先下线对应系统,以保证该服务的正常运行
请保证已获取到了完整的安装部署包(如应用或服务部署包、模型部署包等)
推理服务安装包的目录结构示例如下。
. ├── hliepython │ ├── config │ │ ├── app_config.py │ │ └── __init__.py │ ├── config.yaml │ ├── __init__.py │ ├── main.py │ ├── model_server │ │ ├── engines │ │ │ ├── asr_engine.py │ │ │ ├── base_engine.py │ │ │ ├── embedding_engine.py │ │ │ ├── files │ │ │ ├── image_engine.py │ │ │ ├── __init__.py │ │ │ ├── protocol │ │ │ ├── text_engine.py │ │ │ ├── tts_engine.py │ │ │ └── utils.py │ │ ├── inference_adapter.py │ │ ├── utils │ │ │ ├── convert_gguf_to_hmm.py │ │ │ ├── gguf_view.py │ │ │ ├── read_gguf.py │ │ │ └── test.py │ │ └── worker.py │ └── utils ├── PKG-INFO ├── pyproject.toml └── setup.cfg
HLIEPython 依赖 HLIEvLLM 服务,请在安装HLIEPython 前预先安装好HLIEvLLM。
参考文档HLIEvLLM部署和使用指南安装HLIEvLLM。
(1)在零刻AI网站推理框架栏目下载 HLIEPython 安装包并解压(https://llm.bee-link.cn/frameworks.php)
解压压缩包,进到解压后的文件夹,如“HLIEPython-3.0.0”,执行下面的命令安装HLIEPython:
pipinstall-e.
(2)修改启动配置
修改config.yaml配置文件修改要静态启动的模型配置信息。
vim hliepython/config.yaml
【注】
【必需】将--max-num-batched-tokens和--max-model-len 这两个参数设置成跟模型最大支持的长度一致
静态加载和动态加载当前版本不能同时使用,否则会出现静态和动态模型ID 冲突问题
Yaml 文件格式较为严格,如果启动失败,有config.yaml 相关错误,请检查config.yaml的格式是否正确,例如:缩进,空格等
# 服务运行配置 server: main_port: 7800 log_level: "info" model_root_dir: "/home/useradmin/workspaces/models/v1.2.0" # 模型配置 models: # Qwen3.5-9B 模型 -name: "Qwen3.5-9B" instances: -port: 7801 model_path: "qwen3.5_9B" model_type: "text" # text、embedding、image、asr、tts vllm_config: max-model-len: 65536 max-num-seqs: 1 no-enable-prefix-caching: true max-num-batched-tokens: 65536 additional_config: device_ids: [0] enable_cacheprompt: "False" # # Qwen3.5_VL-35B 模型 # - name: "Qwen3.5-VL_35B" # instances: # - port: 7802 # model_path: "qwen3.5_35b" # model_type: "text" # vllm_config: # max-model-len: 262144 # max-num-seqs: 1 # no-enable-prefix-caching: true # max-num-batched-tokens: 262144 # enable_mm_embeds: true # additional_config: # device_ids: [0] # enable_cacheprompt: "False" # "vit_model_name": "mmproj-qwen3.5-35b-a3b-p256-256K-b1-2core-1d-xh2-v1.3.0-20260420210756.gguf" # # whisper-medium 模型 # - name: "whisper-medium" # instances: # - port: 7803 # model_path: "whisper-medium" # model_type: "asr" # additional_config: # device_ids: [0] # enable_cacheprompt: ""
配置字段说明:
server:用于配置服务端的启动项
main_port:主进程端口号
log_level:日志级别(本版本不可修改)
vllm_log_level:底层hlievllm 的日志级别
model_root_dir:用于存放模型的根目录
models:用于配置静态启动的模型
name:用于配置请求的模型名称,和/v1/models 接口返回的模型ID 一致
instances:模型实例
port:子进程端口号
model_path:相对于model_root_dir的 gguf 模型存放目录,每个模型需要创建独立的模型存放gguf 文件
model_type:模型类型,本版本支持text、embedding、asr、tts
device_ids:设备id
vllm_config:用于配置底层vllm 启动的推理引擎核心参数(【注】这里不维护 vLLM 参数白名单,配置了什么就透传什么;如果参数不是当前vLLM 版本的 AsyncEngineArgs 支持项,底层 vLLM 会按自身逻辑报错。)
additional_config:额外配置,用于添加hliepython 和 vllm 的一些额外配置项
device_ids:配置启动的设备id 编号
enable_cacheprompt:确定是否开启kv cache复用
vit_model_name:用于添加多模态vit 模型
vLLM 推理引擎可支持配置的核心参数:
| 模型配置参数 | tokenizer | 分词器路径 |
|---|---|---|
| dtype | 数据类型 (auto, half, float16, bfloat16, float32) | |
| quantization | 量化方法 | |
| max_model_len | 最大模型长度 | |
| trust_remote_code | 是否信任远程代码 | |
| 并行配置参数 | tensor_parallel_size | 张量并行大小 |
| pipeline_parallel_size | 流水线并行大小 | |
| data_parallel_size | 数据并行大小 | |
| distributed_executor_backend | 分布式执行器后端 | |
| 缓存和内存参数 | gpu_memory_utilization | GPU 内存利用率 (0-1) |
| kv_cache_memory_bytes | KV 缓存内存字节数 | |
| enable_prefix_caching | 启用前缀缓存 | |
| block_size | KV 缓存块大小 | |
| 调度配置参数 | max_num_seqs | 最大序列数 |
| max_num_batched_tokens | 最大批处理 token 数 | |
| max_num_partial_prefills | 最大部分预填充数 | |
| 其他参数 | enforce_eager | 强制使用 eager 执行 |
| disable_log_stats | 禁用统计日志 | |
| seed | 随机种子 |
python-mhliepython.main
主端口:7800
curl-XGEThttp://0.0.0.0:7800/hlie/v1/status
curl-XGEThttp://0.0.0.0:7800/hlie/v1/models
返回参数说明:
data:模型信息列表
id:模型id,显示和本地模型目录名称一致
port:当前模型占用端口,未加载默认为0
status:当前模型是否已加载,未加载默认为0,加载为1
object:固定值"model"
owned_by:所属推理引擎,固定值"HLIEPython"
created:模型信息创建时间
aliases:模型别名(本版本未启用)
tags:模型标识(本版本未启用)
加载模型
根据启动配置参数加载对应模型。
curl-XPOSThttp://0.0.0.0:7800/hlie/v1/models-H "Content-Type: application/json"-d '{ "model_name": "Qwen3-0.6B", "server_config": {"device_ids": [0], "model_type" : "text", "vllm_config": {"max-model-len": 16384, "max-num-seqs": 4, "max-num-batched-tokens": 16384}, "additional_config": {"enable_cacheprompt":"True"}}}'
发送推理请求
curl-XPOSThttp://0.0.0.0:7801/v1/chat/completions-H "Authorization: Bearer sk-123"-H "Content-Type: application/json"-d '{"model": "Qwen3-0.6B", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "讲个笑话"}], "stream": true}'
卸载模型
curl-XDELETEhttp://0.0.0.0:7800/hlie/v1/models/Qwen3-0.6B
通过构造请求头,且请求体中配置指定参数,将该请求发送给服务端,终端界面就可以看到服务端的回复。以下接口参数已兼容 OpenAI API 中的参数,如需增加其他参数,可参考OpenAI API 参数文档根据需求进行添加。命令行请求示例如下:
curl-XPOSThttp://0.0.0.0:7801/v1/chat/completions-H "Authorization: Bearer sk-123"-H "Content-Type: application/json"-d '{"model": "Qwen3.5-9B", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "讲个笑话"}], "stream": false}'将本地图片和网络图片进行对比
curl-XPOSThttp://0.0.0.0:7802/v1/chat/completions-H "Authorization: Bearer sk-123"-H "Content-Type: application/json"-d '{
"model": "Qwen3.5-VL_4B",
"messages": [
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "file:///path/to/images/test.jpg"
}
},
{
"type": "image_url",
"image_url": {
"url": "https://ask.qcloudimg.com/http-save/yehe-6503436/l8m9wq9ivy.jpeg"
}
},
{
"type": "text",
"text": "请描述这两张图片的内容。"
}
]
}
],
"stream": false
}'curl-XPOSThttp://0.0.0.0:7803/v1/audio/transcriptions-H "Authorization: Bearer sk-123"-H "Content-Type: multipart/form-data"-F"model=whisper-medium"-F"language=zh"-F"response_format=json"-F"file=@test.wav"-F"stream=false"
websocket 流式接口:
测试Websocket 接口demo程序:[demo.py]
recv: {"type":"ready","model":"Qwen3-ASR-1.7B","port":7804,"message":"WebSocket ASR 已连接"}
recv: {"type":"ack","message":"配置已更新","language":"zh"} === 模式1:一次性发送整段音频 ===
[FULL] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","chunk_index":1,"final":false} === 模式2:分片实时发送 ===
[CHUNK] recv: {"type":"ack","message":"音频缓冲已清空"}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, and so.","chunk_index":1,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans.","chunk_index":2,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans.","chunk_index":3,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask.","chunk_index":4,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not.","chunk_index":5,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you—ask what you can do for your country.","chunk_index":6,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you—ask what you can do for your country.","chunk_index":7,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you.","chunk_index":8,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","chunk_index":9,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","chunk_index":10,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","chunk_index":11,"final":false}
[CHUNK] recv: {"type":"transcript","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","chunk_index":12,"final":false}
recv: {"type":"done","text":"languageAnd so, my fellow Americans, ask not what your country can do for you. Ask what you can do for your country.","final":true}
【注】当前接口的响应数据是递增的,没有只返回“当前小分片的独立结果”,这是因为ASR 强依赖上下文,单片结果会抖动大、断词严重、标点差。
ws 实现是:
每收到一段分片,把分片追加到服务端缓冲区
用“累计到当前为止的完整音频”重新转写
返回当前完整假设文本
可以通过在请求的return_type 设置full 或 delta 字段返回不同的模式。
curl-XPOSThttp://0.0.0.0:7804/v1/audio/speech \
-H "Authorization: Bearer sk-123" \
-H "Content-Type: application/json" \
-d '{
"model": "Fun-CosyVoice3-0.5B",
"input": "你好呀!的同学们。",
"voice": "default",
"response_format": "wav"
}' \
--outputspeech.wavcurlhttp://0.0.0.0:7805/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-123" \
-d '{
"input": "Your text string goes here",
"model":"qwen3_embed"
}'import requests
import json
import os local_ip = "0.0.0.0"
API_URL = f"http://{local_ip}:7801/v1/chat/completions" # 设置请求头
headers = { "Content-Type" : "application/json",
} # 设置请求体
data = { "model" : "QWen2.5-7b", "messages" : [ { "role" : "system", "content" : "You are a helpful assistant." }, { "role" : "user", "content" : "讲一个笑话" } ]
} # 发送请求
response = requests. post (API_URL, headers=headers, data=json. dumps (data), stream=True) # 处理流式响应
if response. status_code == 200 : for chunk in response. iter_content (chunk_size=None): if chunk : print (chunk. decode ('utf-8'))
else : print (f"Error:{response.status_code},{response.text}")当前应用软件提供了兼容了OpenAI SDK,可执行以下Demo程序访问后端服务程序,注意,如果调用的机器和后端启动的机器不是一台,需要修改以下程序中的local_ip 为后端启动的ip。
软件要求 本程序兼容 Python 3.7 及以上版本。确保安装了适当的 Python 版本以运行该代码。
依赖库 程序需要以下 Python 库:
openai:用于访问 OpenAI API 进行推理调用。
可以通过以下命令安装所需依赖:
pip install openai
当前推理服务兼容了OpenAI SDK,可执行以下Demo程序访问推理服务程序,注意,请修改以下程序中的base_url 为推理服务启动的机器对应的ip。
import os
from openai import OpenAI base_url = "0.0.0.0:7801" def create_chat_completion (messages, use_stream=False): client = OpenAI ( base_url=f"http://{base_url}/v1", api_key="sk-xxx",) response = client. chat. completions. create ( model="QWen2.5-7b", messages=messages, stream=use_stream, max_completion_tokens=100, top_p=0.8, frequency_penalty=1.4,) if use_stream : print ("Streaming response:") for chunk in response : print (chunk. choices [0]. delta. content or "", end="", flush=True) print () else : print ("Non-streaming response:") print (response. choices [0]. message. content) def function_chat (): chat_messages = [ { "role" : "system", "content" : "You are a helpful assistant.", }, { "role" : "user", "content" : "讲一个笑话", } ] create_chat_completion (messages=chat_messages, use_stream=False) if __name__ == "__main__" : function_chat ()
执行脚本:
python3 openai_sdk.py
本文档整理自官方推理框架部署指南,供参考使用。