---
title: eCity-TS-313M
canonical_url: "https://www.modelscope.cn/models/eCityAI/eCity-TS-313M"
md_url: "https://www.modelscope.cn/models/eCityAI/eCity-TS-313M.md"
repository: eCityAI/eCity-TS-313M
last_updated: 2026-11-06
license: apache-2.0
library_name:
  - pytorch
  - onnx
  - onnxruntime
  - tensorrt
frameworks:
  - onnx
  - onnxruntime
  - tensorrt
domain:
  - time-series
downloads: 0
stars: 0
tags:
  - time-series-forecasting
  - multivariate-forecasting
  - quantile-forecast
  - water-utilities
  - onnx
  - onnxruntime
  - tensorrt
---

# eCity-TS-313M

> eCity-TS-313M - eCityAI 在 ModelScope 开源的模型。eCity-TS-313M 是面向水务场景的多变量时间序列预测模型。模型基于 decoder-only、patch 化的 Transformer 构建，注意力在时间轴（因果）与变量轴（全连接）之间交替，分位数输出头提供不确定性区间。本仓库国内节点直连、下载无需代理。本文档仅覆盖推理流程：如何用 ONNX Runtime 与 TensorRT 加载 artifacts、喂数据、读结果；模型已同步发布于 HuggingFace。

eCityAI/eCity-TS-313M 是 ModelScope 魔搭社区上的机器学习模型，采用 apache-2.0 许可。

- **Repository**: eCityAI/eCity-TS-313M
- **License**: apache-2.0
- **Tags**: time-series-forecasting, multivariate-forecasting, quantile-forecast, water-utilities, onnx, onnxruntime, tensorrt
- **Downloads**: 0
- **Stars**: 0
- **Last updated**: 2026-11-06

Source: https://www.modelscope.cn/models/eCityAI/eCity-TS-313M

---

# eCity-TS-313M

eCity-TS-313M 是面向水务场景的多变量时间序列预测模型。模型基于 decoder-only、patch 化的 Transformer 构建，注意力在时间轴（因果）与变量轴（全连接）之间交替，分位数输出头提供不确定性区间。本仓库国内节点直连、下载无需代理。本文档仅覆盖推理流程：如何用 ONNX Runtime 与 TensorRT 加载 artifacts、喂数据、读结果；模型已同步发布于 [HuggingFace](https://huggingface.co/eCityAI-Sup/eCity-TS-313M)。

给定最多 4096 步 × 15 个变量的历史窗口，单次前向即可预测未来 96 步的 9 个分位数，支持供水量、管网流量、压力、水箱液位等场景的区间预测与调度决策。

## 1. 交付物

| 文件 | 路径 | 说明 |
|---|---|---|
| ONNX 计算图 | `artifacts/ecity_ts_313m_15x4096.onnx` | 输入/输出签名见下表 |
| ONNX 外部权重 | `artifacts/ecity_ts_313m_15x4096.onnx.data` | 约 1.3 GB，必须与 `.onnx` 文件放在同一目录 |
| TensorRT 引擎 | `artifacts/ecity_ts_313m_15x4096_fp32.engine` | 约 1216 MB，与构建时的 TensorRT / CUDA / GPU 绑定 |
| 参考样本 | `example/ecity_ts_313m_15x4096.npz` | 固定输入（batch=4）与 FP32 参考输出，供两个 demo 脚本做回归校验 |
| 基准快照 | `example/ecity_ts_313m_15x4096.json` | 发布时记录的一次性 TensorRT batch=4 延迟 / 显存快照 |

### 输入/输出契约

| 名称 | 形状 | 类型 | 说明 |
|---|---|---|---|
| `target` | `[B, 15, 4096]` | float32 | 历史观测；未观测点可填任意值，由 `target_mask` 屏蔽 |
| `target_mask` | `[B, 15, 4096]` | bool | `True` 表示该点已被观测 |
| `series_ids` | `[B, 15]` | int64 | 变量标识；跨 batch 保持稳定，通常为 `0..14` |
| `quantiles` | `[9, B, 15, 96]` | float32 | 分位数 0.1–0.9 × batch × 变量 × 预测步数；中位数为下标 4 |

- `B` 是唯一动态维度；ONNX 与 TensorRT 的优化 profile 均为 `min / opt / max = 1 / 4 / 8`。
- 分位数沿第 0 维排布；TensorRT 内部会把 TopK 重写到最后一维再转回来，对外形状不变。

## 2. 环境搭建

```bash
# 1. 创建独立 Python 环境（推荐 3.12）
conda create -n ecity-ts-313m python=3.12 -y
conda activate ecity-ts-313m

# 2. 安装与 CUDA 12.8 匹配的 PyTorch（TensorRT 路径用其管理显存与 stream）
python -m pip install torch --index-url https://download.pytorch.org/whl/cu128

# 3. 安装运行依赖（numpy、onnxruntime-gpu、tensorrt、torch）
python -m pip install -r requirements.txt
```

- 需要 CUDA 12.x 驱动与 cuDNN 9（cuDNN 随 torch cu128 wheel 附带）。`demo_onnx.py` 会调用 `ort.preload_dlls()`，避免系统库路径中缺少 `libcudnn.so.9` 时 CUDA EP 静默回退到 CPU。
- ONNX 路径只需 `numpy + onnxruntime-gpu`；TensorRT 路径额外需要 `tensorrt + torch`（`demo_trt.py` 用 PyTorch 管理设备显存与 stream，不加载模型权重）。
- 环境自检：

```bash
python -c "import numpy, torch, onnxruntime, tensorrt; print(numpy.__version__, torch.__version__, onnxruntime.__version__, tensorrt.__version__)"
```

- 验证版本：Python 3.12、numpy 1.26.4、torch 2.9.1+cu128、onnxruntime-gpu 1.26.0、TensorRT 10.6.0、8× NVIDIA H200。
- 引擎与构建环境强耦合；更换 GPU 型号、CUDA 或 TensorRT 版本需重新构建。

## 3. 下载模型

`./eCity-TS-313M` 目录由以下下载命令创建，内容与本仓库布局完全一致（`artifacts/`、`example/` 与两个 demo 脚本），下载后即可直接运行：

方式一：命令行（CLI）

```bash
pip install -U modelscope
modelscope download --model eCityAI/eCity-TS-313M --local_dir ./eCity-TS-313M
```

方式二：Python SDK

```python
from modelscope import snapshot_download

model_dir = snapshot_download('eCityAI/eCity-TS-313M', local_dir='./eCity-TS-313M')
```

注意：`artifacts/` 下的 `.onnx` 与 `.onnx.data` 必须放在一起；TensorRT 引擎与硬件绑定，若你的 GPU / CUDA / TensorRT 组合与发布环境（见第 2 节）不同，请改用 ONNX artifact。

## 4. ONNX Runtime 推理

```python
import numpy as np
import onnxruntime as ort

# pip 安装的 cuDNN 不在系统库路径中；需预加载，否则 CUDA EP 会静默回退到 CPU。
ort.preload_dlls()

session = ort.InferenceSession(
    "artifacts/ecity_ts_313m_15x4096.onnx",
    # CUDA EP 默认启用 TF32（10 位尾数），偏差会膨胀到 ~1e-1 量级，需关闭。
    providers=[("CUDAExecutionProvider", {"use_tf32": "0"}), "CPUExecutionProvider"],
)

target = np.asarray(x, dtype=np.float32)[None]              # [1, 15, 4096]
target_mask = np.isfinite(x)[None]                          # [1, 15, 4096]
series_ids = np.arange(15, dtype=np.int64)[None]            # [1, 15]

quantiles = session.run(
    ["quantiles"],
    {"target": target, "target_mask": target_mask, "series_ids": series_ids},
)[0]
# quantiles.shape == (9, 1, 15, 96)
```

- `x` 是 `[15, 4096]` 的历史矩阵；多个站点可堆叠为 `[B, 15, 4096]` 一次前向完成整批预测。
- 可运行示例见 `demo_onnx.py`（会加载 `example/ecity_ts_313m_15x4096.npz` 并与参考输出比对）。
- 仅当 CUDA provider 不可用时才会回退到 CPU，结果一致但慢得多；可用 `session.get_providers()` 查看实际生效的 provider。
- 结果读取：`point = quantiles[4]`（中位点预测），区间为 `quantiles[0]`（P10）与 `quantiles[8]`（P90）。

## 5. TensorRT 推理

本仓库在 `demo_trt.py` 中提供了 `EngineRunner`，直接以 PyTorch CUDA 张量作为设备缓冲，无主机/设备间拷贝：

```python
import torch
from demo_trt import EngineRunner

runner = EngineRunner("artifacts/ecity_ts_313m_15x4096_fp32.engine")

target = torch.as_tensor(x, dtype=torch.float32, device="cuda")[None]      # [1, 15, 4096]
target_mask = torch.isfinite(target).bool()                                # [1, 15, 4096]
series_ids = torch.arange(15, dtype=torch.int64, device="cuda")[None]      # [1, 15]

quantiles = runner.infer(target, target_mask, series_ids)   # GPU 张量, (9, 1, 15, 96)
torch.cuda.synchronize()                                     # 读取或计时前必须同步
```

直接使用 TensorRT Python API 时的关键点：

1. 用 `trt.Runtime(logger).deserialize_cuda_engine(engine_bytes)` 反序列化，再调用 `create_execution_context()`。
2. 每次请求先调用 `set_input_shape(name, shape)`（超出 `1/4/8` profile 时返回 False），再调用 `set_tensor_address(name, data_ptr)`。
3. 输入必须连续且位于 CUDA 上；用 `get_tensor_shape("quantiles")` 在同一设备上分配输出张量。
4. 用 `execute_async_v3(torch.cuda.current_stream().cuda_stream)` 提交，使其与上游 PyTorch 算子共享 stream。
5. execution context 保存当前调用的形状与地址状态，不要跨线程共享（每个 worker 一个 context）。

## 6. 数据集性能

三项指标均为越低越好。在西安兴福林带项目数据集（建分区）上，eCity-TS-313M 相比 TimesFM 将 MAE 降低约 83%、相比 Moirai 降低约 56%；RMSE 分别降低约 79% 与 49%。

| 模型 | MAE | MSE | RMSE |
|---|---|---|---|
| TimesFM | 229.5565 | 504803.1905 | 371.7470 |
| Moirai | 87.3544 | 23699.9194 | 153.0700 |
| eCity-TS-313M | 38.0379 | 6158.1171 | 78.4775 |

## 7. 实测基准（H200，15×4096，fp32）

| 后端 | 指标 | 结果 |
|---|---|---|
| ONNX Runtime (CUDA EP，关闭 TF32) | `max_abs` / `mean_abs` / `p99_abs` | 3.91e-4 / 4.73e-6 / 6.48e-5 |
| TensorRT | `max_abs` / `mean_abs` / `p99_abs` | 3.47e-4 / 4.57e-6 / 6.29e-5 |
| TensorRT，batch=4 | P50 / P95 / P99 / 吞吐 | 142.0 ms / 143.6 ms / 163.2 ms / 28.4 samples/s |

误差以 FP32 参考输出为基准；两个后端都远低于生产可接受的 1e-2。`example/ecity_ts_313m_15x4096.json` 是发布时单独记录的一次性快照（batch=4 的延迟 P50/P95 与峰值显存），与上表存在小幅的运行间波动属正常现象。该网络以归一化、逐元素算子和长序列归约为主，因此 kernel 启动与访存占主导。TensorRT 相对通用运行时的主要收益是去除 Python/框架开销、显存占用更稳定，而非延迟的数量级下降。

## 8. 运行约束

- **batch 范围**：`1 ≤ B ≤ 8`；更大的 batch 需重建引擎或修改 profile。
- **固定形状**：`V=15`、`T=4096`、`H=96` 已固化在计算图中，不能直接喂其他长度。
- **仅 fp32**：4096 上下文下，fp16 在 `transformer.layers.0.ffn.fc2` 中溢出为 inf，随后的 RMSNorm 整体变 NaN。
- **引擎与机器绑定**：TensorRT 引擎与 GPU 架构、CUDA、TensorRT 版本绑定，新环境需重建。
- **线程安全**：单个 execution context 不支持并发调用；并发请为每个线程创建一个 context。
- **缺失值语义**：当前 artifact 以 `has_missing_values=false` 导出，即历史窗口中每个点都被视为已观测。如需对缺口与缺失数据建模，请使用 `has_missing_values=true` 导出的 artifact。

## 9. 常见问题（FAQ）

**Q：预测结果应该如何使用？**
`quantiles[4]` 是中位点预测，`quantiles[0]` / `quantiles[8]` 是 P10 / P90 区间，可用于报数、告警阈值与调度裕度。

**Q：ONNX 能否在没有 GPU 的机器上运行？**
可以，去掉 CUDA provider 即用 CPU。结果一致，但 15×4096 的输入不适合在 CPU 上做在线推理。

**Q：`series_ids` 必须连续吗？**
不必，但必须与各变量的物理含义一一对应，且跨请求保持稳定；否则模型会把不同变量当成同一身份。

**Q：为什么 `.onnx` 文件旁边还有一个 `.onnx.data`？**
权重约 1.3 GB，超过 protobuf 单文件上限，因此使用外部数据。两个文件必须位于同一目录并一起移动。

**Q：多个站点能共享一个 batch 吗？**
可以，把它们的 `target / target_mask` 沿第 0 维堆叠（变量顺序与历史窗口一致），一次前向完成整批预测。

## 引用

eCity-TS-313M 的权重来自开源时间序列基础模型 Toto 2.0。如在工作中使用了本模型，请引用基座论文：

```bibtex
@misc{khwaja2026toto20timeseries,
      title={Toto 2.0: Time Series Forecasting Enters the Scaling Era},
      author={Emaad Khwaja and Chris Lettieri and Gerald Woo and Eden Belouadah and Marc Cenac and Guillaume Jarry and Enguerrand Paquin and Xunyi Zhao and Viktoriya Zhukov and Othmane Abou-Amal and Chenghao Liu and Ameet Talwalkar and David Asker},
      year={2026},
      eprint={2605.20119},
      archivePrefix={arXiv},
      primaryClass={cs.LG},
      url={https://arxiv.org/abs/2605.20119},
}
```

## 致谢

eCity-TS-313M 基于开源时间序列基础模型 [Toto 2.0](https://arxiv.org/abs/2605.20119) 构建，感谢其作者开源发布模型权重与推理代码。本仓库仅覆盖水务场景推理、ONNX / TensorRT 部署适配与数值校验，不包含任何训练代码或训练数据。

## 许可证

本仓库基于 [Apache-2.0 License](LICENSE) 开源；权重继承基座模型的 Apache-2.0 许可证。架构超参与分位数布局内嵌于 ONNX 计算图中，无需单独的配置文件。
