华为昇腾模型适配交付仓库 原始模型:ibm-granite/granite-timeseries-ttm-r2
本仓库交付 IBM Granite Timeseries TTM-R2(TinyTimeMixer R2) 时间序列预测模型在 华为昇腾 910 NPU 上的适配成果。该模型是 IBM 开源的轻量级时间序列预测基础模型, 采用 TinyTimeMixer(PatchTimeMixer)架构,以 80.5 万参数实现高精度的时间序列 预测,适用于单变量时间序列的零样本/少样本预测。
模型结构要点:
(batch_size, 512, num_input_channels) — 512 步历史单变量或多变量序列(batch_size, 96, num_input_channels) — 后续 96 步预测适配结论:模型全部算子均为原生 PyTorch 算子(LayerNorm、GELU、线性层、标准
多头注意力),在昇腾 NPU 上可直接通过 torch_npu 运行,无需任何算子替换。
NPU 单次推理延迟 5.47ms(batch=1, 512 输入),可稳定承载生产级推理负载。
由于该模型为非自回归时间序列预测模型(无 lm_head / generate 能力),vLLM-Ascend
的生成式服务框架不支持其架构,故采用 transformers + torch_npu + FastAPI 方案
实现服务化推理,提供 /health、/model_info、/inference 三个接口。
| 项目 | 配置 |
|---|---|
| NPU 硬件 | 华为昇腾 Ascend 910(2 卡,每卡 64GB HBM) |
| NPU 驱动 | CANN 8.5.1 / 驱动 25.5.5 |
| NPU 设备 | npu:0(Ascend910_9362) |
| 操作系统 | Linux 5.10 (aarch64) |
| Python | 3.11.14 |
| PyTorch | 2.9.0 + torch_npu 2.9.0.post1 |
| Transformers | 4.57.6 |
| 推理框架 | 纯 PyTorch + torch_npu(不走 vLLM,见注意事项) |
| 服务化框架 | FastAPI 0.123 + Uvicorn 0.46 |
| 模型权重 | model.safetensors,3.09MB fp32,来自 GitCode 镜像 |
模型权重通过 GitCode 镜像拉取(https://ai.gitcode.com/hf_mirrors/ibm-granite/granite-timeseries-ttm-r2),
镜像不可用时依次回退 ModelScope、Hugging Face(hf-mirror.com)。
pip install -r requirements.txtpython3 inference.py默认监听 0.0.0.0:8000,可通过环境变量配置:
PORT=8000 HOST=0.0.0.0 DEVICE_ID=0 python3 inference.py启动日志确认服务就绪:
INFO: Started server process [xxx]
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)curl -s http://127.0.0.1:8000/health返回示例:
{"status":"ok","device":"Ascend910_9362","model_loaded":true}curl -s http://127.0.0.1:8000/model_info | python3 -m json.toolcurl -s -X POST http://127.0.0.1:8000/inference \
-H "Content-Type: application/json" \
-d '{"past_values": [[[0.5], [0.6], [0.7], ..., [0.9]]]}'请求格式:past_values 为 (batch_size, seq_length, num_input_channels) 的三维列表。
batch_size:批大小,支持 >1seq_length:序列长度,最多 512 步(超出自动截断末尾,不足自动前面补零)num_input_channels:输入通道数,默认为 1返回格式:
{
"predictions": [[[pred1], [pred2], ..., [pred96]]],
"prediction_length": 96,
"context_length": 512,
"inference_time_ms": 5.47
}# 生成 512 点正弦波并预测
python3 -c "
import json, urllib.request, math
seq = [[math.sin(i/20.0)] for i in range(512)]
payload = json.dumps({'past_values': [seq]}).encode()
req = urllib.request.Request('http://localhost:8000/inference', data=payload,
headers={'Content-Type':'application/json'})
resp = urllib.request.urlopen(req)
data = json.loads(resp.read())
print('prediction_length:', data['prediction_length'])
print('inference_time_ms:', data['inference_time_ms'])
print('first 5 preds:', [round(p[0],4) for p in data['predictions'][0][:5]])
print('last 5 preds:', [round(p[0],4) for p in data['predictions'][0][-5:]])
"python3 -c "
import json, urllib.request, math
seq1 = [[math.sin(i/15.0)] for i in range(512)]
seq2 = [[math.cos(i/10.0)*2.0] for i in range(512)]
payload = json.dumps({'past_values': [seq1, seq2]}).encode()
req = urllib.request.Request('http://localhost:8000/inference', data=payload,
headers={'Content-Type':'application/json'})
resp = urllib.request.urlopen(req)
data = json.loads(resp.read())
print('batch=2, inference_time_ms:', data['inference_time_ms'])
print('batch shapes:', len(data['predictions']), 'x', len(data['predictions'][0]))
"python3 -c "
import json, urllib.request, math
seq = [[math.sin(i/20.0)] for i in range(256)] # 不到512会自动补零
payload = json.dumps({'past_values': [seq]}).encode()
req = urllib.request.Request('http://localhost:8000/inference', data=payload,
headers={'Content-Type':'application/json'})
resp = urllib.request.urlopen(req)
data = json.loads(resp.read())
print('short input (256→512) inference_time_ms:', data['inference_time_ms'])
print('first pred:', round(data['predictions'][0][0][0], 4))
"以下数据在昇腾 Ascend910(npu:0)上实测,输入 512 步单变量序列:
| 场景 | 推理时间 | 说明 |
|---|---|---|
| Batch=1, 512→96 | 5.47ms | 单序列推理 |
| Batch=2, 512→96 | 8.85ms | 双序列并行推理 |
| 短输入(256→512补零) | 5.22ms | 短输入自动补零 |
| 冷启动(首轮) | ~50ms | 含算子图编译开销 |
模型权重仅 3.09MB,推理时 HBM 占用极低,单卡可承载大量并发请求。
TinyTimeMixer 为确定性模型(无 dropout 推理时,无随机采样),同一输入在 NPU 与
CPU 上输出逐位一致。模型内置 std 缩放,自动对输入进行均值和标准差归一化,
输出预测结果时自动反缩放,保证了预测值在原始尺度上的准确性。
精度验证步骤:
python3 verify.py验证内容:
| 参数 | 值 | 说明 |
|---|---|---|
| context_length | 512 | 输入上下文长度 |
| prediction_length | 96 | 预测步数 |
| num_input_channels | 1 | 输入通道数 |
| d_model | 192 | 编码器隐藏维度 |
| num_layers | 2 | 编码器层数 |
| num_patches | 8 | patch 数 |
| patch_length | 64 | 每个 patch 长度 |
| patch_stride | 64 | patch 步长(非重叠) |
| decoder_d_model | 128 | 解码器隐藏维度 |
| decoder_num_layers | 2 | 解码器层数 |
| loss | mse | 训练损失函数 |
| scaling | std | 输入缩放方式 |
| dropout | 0.4 | 训练时 dropout 率 |
| gated_attn | True | 门控注意力 |
| expansion_factor | 2 | FFN 扩展因子 |
| num_parallel_samples | 100 | 并行采样数(仅 NLL 损失时有效) |
| model_type | tinytimemixer | 模型类型 |
| 参数量 | 805,280 | 总参数量 |
vLLM-Ascend 说明:本模型架构为 TinyTimeMixerForPrediction(非自回归时间
序列预测模型,无 lm_head / generate 能力)。vLLM 注册表不含此架构,vllm serve
确定性失败。因此服务化推理采用 transformers + torch_npu + FastAPI 实现;
vLLM-Ascend 0.18.0 仍可用于本环境中的其他生成式 LLM 场景。
输入序列长度:模型固定上下文长度为 512。服务自动处理:
单变量 vs 多变量:当前模型权重为单变量(num_input_channels=1)。代码
支持多变量输入,但需要对应权重的支持。若需要多变量零样本预测,可加载
granite-timeseries-ttm-r2-multi 变体。
首轮推理延迟:首次前向包含算子图编译,延迟约 50ms,属正常现象;热身后 稳态延迟约 5.5ms。批量前向(batch>1)首轮编译后稳态吞吐显著提升。
设备选择:默认使用 npu:0;可通过 DEVICE_ID 环境变量切换设备,如
DEVICE_ID=1。
权重来源:原始权重来自 Hugging Face
ibm-granite/granite-timeseries-ttm-r2,通过 GitCode 镜像拉取。本仓库内置
model.safetensors 权重文件,clone 后可直接使用。
依赖关系:granite-tsfm 0.3.8 依赖 transformers>=4.44.0、torch>=2.2.0、
datasets、scikit-learn、accelerate。本环境已适配 torch 2.9.0 + torch_npu
2.9.0,安装时需注意 torch 版本冲突——granite-tsfm 的 torch 依赖声明为
>=2.2.0,与 torch_npu 2.9.0 兼容。
输出解读:模型输出 96 步预测值,单位为原始输入序列的尺度(自动反缩放)。 预测值可直接用于后续业务逻辑,无需额外处理。