Skip to content

AI 应用的成本控制与优化

从一个月烧 $500 到 $50——手把手教你把 AI 应用的账单砍下来,同时不牺牲用户体验。


7. 推理优化:同样的质量,更少的计算

前面几章聚焦在"少调 API"和"每次调 API 少花 Token"。这一章换个角度——让 API 调用本身变得更高效,或者干脆不调 API。


7.1 流式输出:体验更好,成本不变

流式输出不省钱,但"感觉"更快

流式 vs 非流式的对比:

  非流式(等完整响应):
  ─────────────────────────────────────
    用户发问 → 等待 2-3 秒 → 一次性显示全部回答
    → 用户看到空白页面等 3 秒 → 体验差
    → Token 消耗:和流式完全一样
    → 成本:一模一样

  流式(逐 Token 输出):
  ─────────────────────────────────────
    用户发问 → 200ms 后开始逐字显示 → 2-3 秒全部显示完
    → 用户 200ms 就看到反馈 → 体验好
    → Token 消耗:和非流式完全一样
    → 成本:一模一样

  结论:
    流式不省钱,但大幅提升用户体验
    用户感知延迟从 3 秒降到 200ms
    → 这是"免费的午餐"——不花钱就能提升体验

流式输出实现

python
from openai import OpenAI
from fastapi import FastAPI
from fastapi.responses import StreamingResponse

client = OpenAI()
app = FastAPI()

async def stream_chat(question: str, system_prompt: str = "简洁回答"):
    """流式响应生成器"""
    stream = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": question}
        ],
        stream=True,
        max_tokens=500
    )

    for chunk in stream:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

@app.get("/api/stream")
async def stream_endpoint(question: str):
    return StreamingResponse(
        stream_chat(question),
        media_type="text/event-stream"
    )

流式 + 缓存:缓存命中时直接返回完整响应(非流式),未命中时用流式。用户甚至分不出来区别——缓存命中"秒回",未命中"逐字显示",体验都很好。

7.2 批处理与请求合并:减少 API 调用次数

为什么要批处理

单次调用 vs 批处理的效率对比:

  场景:需要对 100 条用户评论做情感分析

  方式 1:逐条调用(100 次 API)
  ─────────────────────────────────────
    每次 API 调用有固定开销:
      → 网络往返:50-100ms
      → System Prompt:每次都重复发送
      → 连接建立、鉴权等

    100 条 × System Prompt 30 tokens = 3000 tokens 浪费
    总耗时:100 × 300ms = 30 秒

  方式 2:批量调用(1 次 API,一次处理 10 条)
  ─────────────────────────────────────
    10 批 × 10 条/批
    System Prompt 只发 10 次 = 300 tokens
    总耗时:10 × 500ms = 5 秒

    节省 Token:2700(System Prompt 少发 90 次)
    节省时间:25 秒

批处理实战

python
def batch_analyze(
    texts: list[str],
    batch_size: int = 10,
    model: str = "gpt-4o-mini"
) -> list[dict]:
    """批量文本分析:一次请求处理多条"""

    results = []

    for i in range(0, len(texts), batch_size):
        batch = texts[i:i + batch_size]
        numbered = "\n".join(f"{j+1}. {t}" for j, t in enumerate(batch))

        response = client.chat.completions.create(
            model=model,
            messages=[{
                "role": "user",
                "content": f"""对以下评论做情感分析,返回 JSON 数组:
[{{"id": 1, "sentiment": "positive/negative/neutral"}}]

评论列表:
{numbered}"""
            }],
            response_format={"type": "json_object"},
            max_tokens=200
        )

        batch_results = json.loads(response.choices[0].message.content)
        results.extend(batch_results.get("results", []))

    return results

# 100 条评论,只需 10 次 API 调用
comments = ["产品很好用!", "太贵了", "一般般吧", ...]  # 100 条
results = batch_analyze(comments, batch_size=10)

7.3 本地部署 vs 云端 API:什么时候划算

完整的成本计算

云端 API 月成本(GPT-4o-mini):
─────────────────────────────────────
  月请求量 × 单次成本

  10 万次 × $0.0009 = $90/月
  50 万次 × $0.0009 = $450/月
  100 万次 × $0.0009 = $900/月


本地部署月成本(Llama 3 8B,单卡 A10G):
─────────────────────────────────────
  云 GPU 租金:$600/月(AWS g5.xlarge)
  运维人力:$300/月(兼职 10%)
  电费/带宽:$50/月
  总计:$950/月

  可处理量:
    推理速度:~50 tokens/秒
    单次平均 500 tokens → 10 秒/次
    月处理量:260 万次(满载运行)

  等效单次成本:$950 / 260 万 = $0.00037/次
  → 比 API 便宜 2.4 倍


本地部署月成本(自购 RTX 4090):
─────────────────────────────────────
  硬件摊销:$1600 / 24 月 = $67/月
  电费:$30/月
  运维:$100/月(DIY)
  总计:$197/月

  等效单次成本:$197 / 260 万 = $0.00008/次
  → 比 API 便宜 11 倍!
  → 但需要 GPU 运维能力

本地部署快速上手

python
# 用 Ollama 一键部署本地模型
# 安装:brew install ollama(macOS)

# 下载并运行模型
# ollama pull llama3:8b
# ollama serve

import requests

def local_chat(question: str, model: str = "llama3:8b") -> str:
    """调用本地 Ollama 模型"""
    response = requests.post("http://localhost:11434/api/generate", json={
        "model": model,
        "prompt": question,
        "stream": False
    })
    return response.json()["response"]

# 完全免费(只有电费)
answer = local_chat("Python 的 GIL 是什么?")

何时选择本地部署

条件API本地部署
月请求量 < 50 万✅ 更划算
月请求量 > 100 万❌ 太贵✅ 更划算
需要数据隐私❌ 数据出网✅ 数据不出网
有 GPU 运维能力-✅ 前提条件
需要最新模型✅ 自动更新❌ 手动更新
需要快速启动✅ 即开即用❌ 部署周期 1-3 天

务实建议:用 Ollama 在本地跑一个 8B 模型做简单任务(分类、提取),复杂任务仍走 API。这种混合模式对大多数团队最友好。

7.4 模型量化:用更小的模型做同样的事

量化是本地部署中最重要的优化——它让你在更便宜的 GPU(甚至 CPU)上跑更大的模型。

量化的直觉

量化 = 用更少的精度存储模型参数

  原始模型(FP32,32位浮点):
    参数值:0.12345678
    每个参数占 4 字节
    Llama 3 8B → 需要 32GB 显存

  FP16(16位半精度):
    参数值:0.1235(精度略低)
    每个参数占 2 字节
    Llama 3 8B → 需要 16GB 显存

  INT8(8位整数):
    参数值:近似为 31/255
    每个参数占 1 字节
    Llama 3 8B → 需要 8GB 显存

  INT4(4位整数):
    参数值:近似为 2/15
    每个参数占 0.5 字节
    Llama 3 8B → 需要 4GB 显存 ← 普通笔记本就能跑!

  规律:
    精度每降一级 → 显存约减半 → 速度略有提升
    质量损失:FP16≈0% / INT8≈1-2% / INT4≈3-5%

量化模型的实际表现

量化级别显存需求推理速度质量损失适合硬件
FP1616GB基准~0%A100 / 4090
INT8 (Q8)8GB提升 10%1-2%3090 / M2 Pro
Q5_K_M5.5GB提升 20%2-3%3060 / M2
INT4 (Q4)4GB提升 30%3-5%普通笔记本
Q2_K3GB提升 40%8-15%⚠️ 质量明显下降

Ollama 使用量化模型

bash
# 不同量化级别的 Llama 3 8B
ollama pull llama3:8b         # 默认 Q4_0,~4.7GB
ollama pull llama3:8b-q8_0    # INT8,~8.5GB,质量更好
ollama pull llama3:8b-fp16    # 半精度,~16GB,最佳质量

# 对比不同量化级别的文件大小
# Q4:   4.7GB  → 适合 8GB 显存
# Q8:   8.5GB  → 适合 16GB 显存
# FP16: 16GB   → 适合 24GB+ 显存

量化选型建议

你的硬件是什么?

├── 没有 GPU(纯 CPU)
│   └── Q4 量化 + 7B 模型
│       → 速度慢(~10 tok/s),但能跑
│       → 适合开发测试,不适合生产

├── 8GB 显存(RTX 3060 / M2)
│   └── Q4 量化 + 8B 模型
│       → ~30 tok/s,足够流畅
│       → 适合个人/小型生产

├── 16GB 显存(RTX 4080 / M2 Pro)
│   └── Q8 量化 + 8B 模型 或 Q4 + 14B 模型
│       → ~50 tok/s,质量好
│       → 适合中型生产

└── 24GB+ 显存(RTX 4090 / A100)
    └── FP16 + 8B 或 Q8 + 70B
        → 最佳质量 + 高速
        → 适合大规模生产

量化的价值:量化让"本地部署"的门槛大幅降低。INT4 量化后的 8B 模型只需 4GB 显存——一台 MacBook Air 就能跑。这意味着你可以用几乎零成本处理简单任务(分类、提取),把 API 预算留给真正需要的复杂场景。


本章小结

知识点要点
流式输出不省钱但提升体验(感知延迟从 3s→200ms)
批处理合并请求减少 System Prompt 重复发送
本地部署成本自购 4090 等效 $0.00008/次,比 API 便宜 11 倍
盈亏平衡月请求 > 100 万次本地部署更划算
Ollama一键部署本地模型,零配置
模型量化INT4 将 16GB 模型压缩到 4GB
量化质量损失Q8≈1-2%,Q4≈3-5%,Q2≈8-15%
混合模式简单任务用本地,复杂任务走 API

下一章预告:监控与可观测性——看见你的钱花在哪。我们会构建 Token 用量监控仪表板,实现按功能、按用户、按时段的成本归因,以及评估一个 AI 功能是否值得保留的 ROI 框架。

坚持是一种品格