GLM-5.3 开始优化自己的推理底座:早期 RSI 到底意味着什么

2026-09-20 19 预计阅读时间: 1 分钟
来源: oschina.net AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:10 分钟

智谱将 GLM-5.3 的能力描述为递归自我改进(Recursive Self-Improvement,RSI)的早期形态。关键变化并不是模型又能多写几段代码,而是它开始参与优化承载自身推理的生产系统:模型既是被服务的对象,也进入了服务系统的改进链路。

这还不能直接等同于完整 RSI,但它已经把问题从“AI 辅助工程师开发”推进到了“AI 改进自身运行环境”。在超过 10 万张国产芯片组成的部署规模上,哪怕只改善少量延迟、吞吐或资源利用率,也可能产生显著的工程价值。

从代码生成走向可验证的改进闭环

普通代码助手的工作通常在提交补丁后结束。早期 RSI 形态需要形成更长的闭环:

  1. 从生产指标、性能分析结果和故障记录中发现瓶颈。
  2. 理解推理框架、算子、调度策略和硬件约束。
  3. 生成代码、配置或部署方案的候选变更。
  4. 在隔离环境中编译、测试和压测。
  5. 根据延迟、吞吐、正确率、错误率和成本判断结果。
  6. 保留有效变更,并把失败结果反馈到下一轮分析。

这里最重要的并不是“模型修改了自己的代码”,而是优化对象、执行者和反馈信号开始出现在同一个系统中。只有反馈能够量化并进入下一轮决策,自动化修改才可能积累成持续改进。

不过,这类闭环仍然通常由工程师定义目标、权限和发布门槛。模型是否能长期自主设定目标、修改更核心的模型或训练过程,以及连续跨越多个版本积累能力,仅凭当前信息还不能确认。因此,把它称为早期 RSI 比称为完整自主进化更准确。

为什么推理系统是一个现实的起点

生产推理系统拥有清晰而密集的反馈信号,非常适合模型参与优化。一次改动是否有效,可以通过首 Token 延迟、P95/P99 延迟、每秒 Token 数、显存占用、功耗、错误率和输出一致性来判断。

大规模国产芯片集群还会放大系统层面的复杂性。不同硬件、驱动、通信库和算子实现可能产生长尾问题;调度策略也必须同时处理批次大小、上下文长度、KV Cache、并行方式和请求优先级。人工逐项搜索组合空间的成本很高,而模型可以读取代码和性能数据,提出候选方案,再交给自动化流水线验证。

这也说明了为什么 RSI 的早期形态更可能先出现在推理基础设施,而不是直接修改模型权重。基础设施优化的目标更明确、实验周期更短,也更容易回滚。模型可以先在边界清晰的工程问题中证明自己,而不必立即获得修改训练数据或核心参数的权限。

可以这样实践:给候选推理服务设置性能门禁

下面是一个可以直接运行的最小压测脚本。假设基线服务和候选服务都提供兼容 /v1/chat/completions 的 HTTP 接口。它不能复现 GLM 团队的内部系统,只展示如何把模型生成的优化方案接入一个可量化、可拒绝的验证环节。

将代码保存为 bench_gate.py,按实际环境修改模型名、接口地址和门槛:

#!/usr/bin/env python3
import argparse
import json
import math
import os
import sys
import time
import urllib.request
from concurrent.futures import ThreadPoolExecutor


def percentile(values, ratio):
    values = sorted(values)
    index = max(0, math.ceil(len(values) * ratio) - 1)
    return values[index]


def send_request(endpoint, model, timeout):
    payload = json.dumps({
        "model": model,
        "messages": [{"role": "user", "content": "用三句话解释 KV Cache。"}],
        "temperature": 0,
        "max_tokens": 96,
    }).encode("utf-8")
    headers = {"Content-Type": "application/json"}
    token = os.getenv("API_TOKEN")
    if token:
        headers["Authorization"] = f"Bearer {token}"

    request = urllib.request.Request(endpoint, data=payload, headers=headers)
    started = time.perf_counter()
    try:
        with urllib.request.urlopen(request, timeout=timeout) as response:
            response.read()
            ok = 200 <= response.status < 300
    except Exception:
        ok = False
    return ok, time.perf_counter() - started


def benchmark(endpoint, model, requests, concurrency, timeout):
    started = time.perf_counter()
    with ThreadPoolExecutor(max_workers=concurrency) as pool:
        results = list(pool.map(
            lambda _: send_request(endpoint, model, timeout),
            range(requests),
        ))

    wall_time = time.perf_counter() - started
    latencies = [latency for ok, latency in results if ok]
    if not latencies:
        return {"success_rate": 0.0, "p95_ms": float("inf"), "rps": 0.0}

    return {
        "success_rate": len(latencies) / requests,
        "p95_ms": percentile(latencies, 0.95) * 1000,
        "rps": len(latencies) / wall_time,
    }


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--baseline", required=True)
    parser.add_argument("--candidate", required=True)
    parser.add_argument("--model", required=True)
    parser.add_argument("--requests", type=int, default=100)
    parser.add_argument("--concurrency", type=int, default=8)
    parser.add_argument("--timeout", type=float, default=30)
    args = parser.parse_args()

    baseline = benchmark(
        args.baseline, args.model, args.requests, args.concurrency, args.timeout
    )
    candidate = benchmark(
        args.candidate, args.model, args.requests, args.concurrency, args.timeout
    )
    print(json.dumps({"baseline": baseline, "candidate": candidate}, indent=2))

    passed = (
        candidate["success_rate"] >= 0.99
        and candidate["success_rate"] >= baseline["success_rate"]
        and candidate["p95_ms"] <= baseline["p95_ms"] * 0.97
        and candidate["rps"] >= baseline["rps"] * 1.03
    )
    print("PASS" if passed else "REJECT")
    return 0 if passed else 1


if __name__ == "__main__":
    sys.exit(main())

运行方式如下:

export API_TOKEN='replace-with-your-token'
python3 bench_gate.py \
  --baseline http://baseline.example/v1/chat/completions \
  --candidate http://candidate.example/v1/chat/completions \
  --model your-model-name \
  --requests 500 \
  --concurrency 16

这个示例要求候选版本成功率不低于 99%,P95 延迟至少改善 3%,吞吐至少提高 3%。真实生产环境还应加入预热、长短请求混合、输出 Token 数归一化、结果质量校验和多轮交替测试,避免缓存状态或测试顺序造成误判。

把自动改进关进工程护栏

模型能够提出底层优化,并不意味着它应该直接获得生产发布权限。更稳妥的系统应把“提出变更”和“批准上线”拆开:模型可以读取经过脱敏的性能数据,在受限分支生成补丁;CI 负责静态检查、单元测试、正确性对比和性能测试;部署平台只允许通过门禁的镜像进入灰度环境。

推理优化尤其需要防范几类假提升:用输出质量换吞吐、只优化单一输入长度、把负载转移到其他节点,以及在特定芯片或驱动版本上产生回归。性能指标之外,还应固定一组质量评测样本,并检查数值误差、拒答行为、工具调用格式和长上下文稳定性。

采用这类能力时,可以从以下边界开始:

  • 先开放配置、调度和非关键算子等容易回滚的优化对象。
  • 所有候选变更必须带基准数据、环境指纹和可复现实验命令。
  • 将质量、安全性和稳定性设为硬门槛,成本与速度只在门槛内优化。
  • 使用灰度流量和自动回滚,不让一次离线压测直接决定全量发布。
  • 保存失败实验,使模型不会反复尝试同一种无效优化。
  • 定期检查评价函数,防止系统只追逐容易量化的代理指标。

GLM-5.3 所展示的信号,价值不在于宣布“完整 RSI 已经到来”,而在于给出了一个更具体的判断标准:当模型能够理解承载自己的系统、提出修改、接受真实指标反馈,并参与下一轮改进时,自我改进就不再只是抽象概念。接下来真正决定上限的,将是闭环能覆盖多深,以及人类能否为这个闭环设计可靠的目标、权限和制动机制。


相关推荐