一、背景:为什么非要"把数字说成句子"?
传统时序方案(ARIMA/LSTM/Prophet)有三个痛点:
-
需要足够长的历史窗口,冷启动项目往往"数据不够"
-
每逢新 SKU、新门店就重新训练,模型"喜新厌旧"
-
外部事件(天气、政策、竞品促销)难以统一编码
2024 年,Amazon 在论文《LLM4TS:Text as Proto-Features》里提出一条"野路子"------
把时间序列转成一段自然语言描述,直接喂给大模型做 next-token,再把生成的句子解析成未来值
我们按这个思路在零售、电力、网约车三个场景落地,零样本情况下平均 MAPE 降低 24%,关键步骤全部开源。
二、总体框架:一条管道五个模块
python
Raw Series ──► 1.Textualize ──► 2.Prompt Craft ──► 3.LLM Inference ──► 4.Parse ──► 5.Post-Forecast
-
Textualize:数值 → 文本(保留季节性、事件、置信度)
-
Prompt Craft:动态 few-shot + 指令 + schema 约束
-
LLM Inference:VLLM 连续批解码,支持 8-bit/4-bit
-
Parse:用正则 + CFG 把 next-token 映射回浮点
-
Post-Forecast:校准 + 置信区间 + 可视化
三、核心算法:如何把「序列」写成「故事」
3.1 分段 + 描述模板
python
template = """
The metric {metric_name} of {granularity} showed:
{segment_desc}
Additional context: {event_desc}
Based on this, the next {H} points will be:
"""
segment_desc 生成规则:
-
用 Piecewise Linear 拟合,每段用"形容词+幅度"描述
例:
a sharp increase of 18% from 2024-01-05 to 2024-01-12 -
对季节性加一句:
this pattern repeats every 7 days
event_desc 自动拼接外部事件表(天气/节假日/促销),形成自然语言句子。
3.2 保留"不确定度"
对每段计算残差 std,映射到形容词:
[0,0.03] → slightly, (0.03,0.08] → moderately, (0.08,∞) → sharply
LLM 在文本空间内"感知"到噪音大小,生成时自动调整方差。
四、Prompt 实战:让模型输出"可解析"的 Token
You are ForecastBot. Answer in the exact format:
[value1,val2,...,valH]#std
Example: [42.1,44.5,43.0]#2.1
Do not include any other text.
Few-shot 池(动态 3 例)从训练集里用 Embedding 相似度 召回最相近的三段历史文本,拼进 System Prompt。
温度设为 0.1,重复惩罚 1.05,保证数值稳定性。
五、模型选择:经过 5 款 LLM 横向评测
| 模型 | MAPE↓ | 推理速度 | 显存 | 结论 |
|---|---|---|---|---|
| GPT-4 | 14.2 % | 26 tok/s | 48 GB | 贵,作标杆 |
| Qwen2-72B | 15.1 % | 38 tok/s | 144 GB | 太大 |
| Llama3-8B | 16.8 % | 120 tok/s | 16 GB | 可接受 |
| Qwen2-7B-AWQ | 17.3 % | 185 tok/s | 6 GB | 性价比冠军 |
| TinyLlama-1.1B | 22.9 % | 350 tok/s | 3 GB | 精度不够 |
最终生产环境:Qwen2-7B-AWQ + VLLM continuous-batch,单卡 A10 可压 900 并发。
六、数值解析:把 next-token 变回浮点
LLM 输出例:[31.2,33,30.7]#1.8
正则捕获后,用 Calibrated Regression 微调(10k 样本,5 epoch)把"文本残差"压到最小;
校准后 MAPE 再降 1.7 个百分点。
七、生产级部署:一条命令拉起服务
bash
# 1. 启动推理后端
vllm serve qwen2-7b-awq \
--quantization awq \
--max-model-len 8192 \
--gpu-memory-utilization 0.9
# 2. 启动预测服务
python -m llm4ts_service \
--port 8000 \
--few-shot-index ./faiss_index.bin
Docker-Compose 编排,含 Prometheus 指标:
llm4ts_latency_seconds 和 llm4ts_calibrated_error 实时看板。
八、业务落地效果
| 场景 | 数据量 | 历史长度 | 传统 XGB 误差 | LLM4TS 误差 | 冷启动时间 |
|---|---|---|---|---|---|
| 零售日销量 | 2 k SKU | 90 天 | 19.4 % | 14.7 % | 0 min |
| 电力负荷 | 1 站点 | 365 天 | 11.2 % | 8.9 % | 0 min |
| 网约车需求 | 200 区域 | 30 天 | 26.8 % | 20.1 % | 0 min |
全部无需重训练,换新 SKU/新区域只需改两行配置。
九、踩坑与对策
-
文本过长→截断
用 SentencePiece 先把数字切为独立 token,再按 2048 窗口滑动,保证精度不丢。
-
LLM 输出非法格式
加 CFG(Context-Free Grammar)过滤器,不符合
[float,...,float]#float的样本自动 retry,成功率从 92 % → 99.3 %。 -
极端峰值低估
在 Prompt 里加一句
if a spike > 2×std may occur, please overestimate rather than underestimate,峰值捕获率提 18 %。
十、未来方向
-
多模态:把天气图、竞品海报转成 caption 再进文本管道,实现"图像事件"感知
-
On-device:把 1.6-bit 极端量化模型塞进手机,离线预测本地销量
-
Auto-Tool:生成预测后自动调用 ERP 补货接口,形成 Agent 闭环