这是对以下活动的提交Hacktoberfest 开源 AI 挑战赛第 4 周:机器中的幽灵

2022-06-02 03:17:03 UTC   I_PD3_THETA   0.0540137
2022-06-02 03:17:08 UTC   I_PD3_THETA   0.0462915
2022-06-02 03:17:13 UTC   I_PD3_THETA   0.0000000
2022-06-02 03:17:18 UTC   I_PD3_THETA   0.0000000
2022-06-02 03:17:23 UTC   I_PD3_THETA   0.0025708

十秒钟的空白。由一艘已不复存在的航天器上的光传感器记录。

ESA 的 OPS-SAT 于2024 年 5 月 22 日在大气层中烧毁。它的工程师们已经各奔东西。没有人留下来追问 03:17:13 发生了什么。

去问聊天机器人,它照样会告诉你答案。传感器故障。一次重启。一次日食。听起来言之凿凿,而它其实是在编造,因为档案里没有任何内容说明原因。

所以我搭建了一场降神会,只立一条规矩:谁都不许替死者发言。

最后一颗卫星把档案交给两个开放模型:

  • TabPFN聆听 OPS-SAT 留下的每一个信号,并判断哪些看起来不对劲。在官方基准测试上,它击败了发布该数据集的论文中最好的模型,而且从未运行过训练循环。
  • Qwen3-8B,在 Tinker 上微调,花费 83 美分,阅读任务文档,并且只被允许说出文档里写的内容。

问它为什么灯在 03:17:13 熄灭了,你会得到一位灵媒所能给出的最诚实的句子:

“该信号行为的根本原因未在档案中记录。”

开始之前先坦白一件事。我的模型看了那十秒钟,判定它们为0.098:大概没问题。它错了。这次失误被故意保留在演示中。

你即将读到的内容

  • TabPFN 的结果:在官方 OPSSAT-AD 测试集划分(529 个片段,仅运行一次,已记录)上,TabPFN-v2 得分AUCPR 0.996、F1 0.982、MCC 0.977。已发表的最佳模型(一篇发表于Scientific Data,2025 年的 FCNN)得分为0.979 / 0.946 / 0.932。
  • 使用与论文相同的特征,没有训练循环:仅使用论文的 18 个特征,TabPFN 依然胜出:0.989 / 0.950 / 0.937。它还以约0.02 AUCPR的优势击败了我调优过的 Random Forest、XGBoost 和 LightGBM。
  • Tinker 的结果:在 Qwen3-8B 上的一个 LoRA 将任务文档的结构化抽取从65.3% 提升到 93.0%字段级精确匹配(验证集),全部花费仅 83 美分。在完全留出的测试文档上,它从72.2% 提升到 86.3%(配对 p = 6×10⁻¹⁶)。
    • 逐字复制的证据:81% → 100%。
    • 通过所有自动化检查的调查笔记:56% → 100%。
  • 成本: 0.22 美元用于最终模型。在 Tinker 上的全部花费为 0.83 美元每一次运行、学习曲线、我故意终止的一次运行,以及每一次评估。
  • 诚实记录: 1 次误报和 3 次漏报异常在 529 个片段中(误报和一次漏报是演示中故意设置的),并且0 个凭空捏造的根本原因来自任一模型。我还展示了我在哪些地方未达到我自己设定的 95% 目标,以及微调让唯一一个任务变得更差。
  • 你可以保留它:适配器运行离线在笔记本电脑上通过 llama.cpp 运行,无需网络,也无需 API 密钥。它与托管模型在100% 的字段上一致。

The Last Satellite: a shader-lit Earth, a decaying orbit, and a console that reads what OPS-SAT left behind

问题在于:一颗死去的卫星无法解释自己

OPS-SAT 是 ESA 的飞行实验室:一颗立方星,ESA 以外的团队可以向其上传实验。在四年半的时间里,它向地球传回了数千个遥测片段。然后,用其任务结束报道的话说,它“受到了 2024 年初开始的近期意外强烈的太阳活动增强的影响”,并提前坠落。

它传回的部分内容现在OPSSAT-AD:

  • 来自三个磁力计和六个光电二极管的 2,123 个遥测片段;
  • 每个片段由三名 ESA 运行工程师和两名 ML 专家标注为正常或异常。

标签说明有某处出了问题。档案中没有任何内容说明为什么。

这就是陷阱。把现代 AI 指向这个档案并问“第 204 个片段发生了什么?”,它会给你一个自信、看似合理、完全编造的故事。传感器故障。一次重启。宇宙射线。数据无法反驳它,因为能反驳的人已经不在了。

你必须担心的失败不是“模型错了”。而是“模型编造了一段档案中并不存在的记忆,而你相信了它”。

今天已有的,以及差距

方案 它能给你什么 它无法告诉你什么
读论文 一个基准测试:FCNN 的 AUCPR 为 0.979 这些片段中哪些应该先看,或者文档对它们说了什么
训练你自己的深度模型 也许能复现论文中的数字,在跑完一个训练循环之后 它的概率是否有意义(校准)
问一个通用聊天机器人 一段流畅的解释 其中是否有哪怕一个词来自档案
The Last Satellite 一个经过校准的异常队列、带引用的文档、每个片段一张卡片 它会告诉你它不知道什么:“档案中未记录根本原因。”

我构建了什么

The Last Satellite是一个任务记忆引擎一个档案调查控制台,配备两个开源模型、一个证据层和一条规则。

  • TabPFN-v2读取每一个归档片段,并给出一个校准后的概率表示它是否异常。它将全部 529 个测试片段排序为优先处理 / 排队 / 归档并显示哪些实测特征驱动了每一项评分。
  • Qwen3-8B + 一个 Tinker LoRA读取任务文档。它提取8 字段、来源关联的记录,重建时间线(事件日期与发布日期分开保留),解释遥测术语并附引用,并将调查笔记分为已知和未知。
  • 屏幕上的每一条陈述要么[measured]来自原始信号,要么[cited]来自文档,逐字引用。
  • 除非来源明确说明,否则绝不断言根本原因,而档案中没有逐片段的故障报告。所以它如实说明。unless a source states one, and the archive has no per-segment incident reports. So it says so.
  • 分析师拥有最终决定权:确认、拒绝或调查,作为反馈存储。
  • 导出:一键将文档、记录、卡片、反馈和所有评估文件打包成一个可移植的任务记忆档案。
  • 控制台是一次从轨道到再入的沉浸式滚动。在它背后,是一颗由着色器点亮的地球,城市灯光如烛火般燃烧,还有一颗微小的 CubeSat,其轨道在你阅读时逐渐衰减。最后,星球暖化为万寿菊色,卫星划入画面。

为什么它契合 Ghost in the Machine:本周从万圣节之夜延伸到亡灵节,此时过去与现在之间的界线被认为最为稀薄。OPS-SAT 是最字面意义上的幽灵:一台已不复存在的机器,仍在通过 303,493 条归档读数说话。

亡灵节不是关于害怕逝者。它是关于准确地记住他们:祭坛上摆放着他们真实的照片、他们真正喜爱的食物、他们真实的故事。所以控制台也照此构建。万寿菊与烛光,而非恐怖。卫星自己的话语就是供品,每一条都有来源。而有一条降神会通常会打破的规则:没有人可以把话塞进幽灵的嘴里。不是我,也不是语言模型。实测、引用,或未知。

演示

上面的视频就是完整导览。控制台在运行时与实时 FastAPI 后端通信。没有它时,会回退到一个标注过的真实 API 响应归档快照,因此它在任何地方都能运行。

本不该出现的信号。从六根蜡烛中选一根:来自官方测试集的六个真实片段,标签隐藏。逐步查看信号、18 个测量特征、TabPFN 的概率、文档、最相似的历史片段,以及调查卡片。然后揭示真相。

True positive: a 16-sample run of exact zeros, P = 1.000, prioritise. The card separates what is measured, what is cited, and what is not known.

以及它漏掉的那一个。演示集刻意包含了误报和一次漏检的异常。注意摘要上的横幅:微调后的解释器草稿被验证器拒绝,因此卡片回退为朴素、确定性的文本。详见下文。

Missed anomaly: P = 0.098, below the threshold chosen on training data. Shown, not hidden.

向档案提问。它会告诉你它不知道什么。

Mission Memory: cited answers on the left; "missing from the archive" on the right

队列。529 个片段按 TabPFN 排序,每个都配有一张卡片和三个按钮:确认、拒绝、调查。

Investigation queue with an open card

代码

GitHub logo advikdivekar/wake

OPS-SAT 的任务记忆引擎(存档):TabPFN 遥测分析器 + 经 Tinker 微调的 Qwen3-8B 解释器。

最后的卫星:任务记忆引擎

它的任务结束了。它的记忆没有。

OPS-SAT 是 ESA 的飞行实验室,一颗于2024 年 5 月 22 日再入大气层的立方星。本项目是一个基于其真实、公开的遥测数据和文档构建的存档分析系统。它分为两部分:

  • 遥测分析器(TabPFN)。对每个存档遥测片段,它估计 P(异常),解释哪些测量特征驱动了该估计,并将片段排入调查队列。
  • 任务记忆解释器(Qwen3-8B + 在 Tinker 上微调的 LoRA)。它将公开任务文档转化为结构化、带来源链接的记录。它把已知的内容与未知的内容分开,并且从不臆造根本原因。

一个证据层将两者结合成调查卡片。卡片上的每条陈述要么是测量所得,要么是引用而来,分析师可以确认、拒绝或调查它。

这里没有任何实时内容。下面的所有数字均由脚本生成……

我是如何构建它的

贯穿始终的规则:模型负责阅读,代码负责测量,绝不声称档案无法展示的内容。

The models read. Code measures. Nothing is claimed that the archive cannot show.

语言模型是出色的读者,却是糟糕的证人。TabPFN 是极佳的估计器,但概率不是解释。因此每项工作都交给能为其负责的一方,并且五项独立检查横亘在模型与屏幕之间:

  1. 输出可解析转换为 8 字段 schema(Pydantic)。
  2. 每一句引用都逐字存在于其源文档中(子串检查)。
  3. 通道 ID 和日期经过交叉核对由从未见过该模型的独立正则读取器完成。
  4. “根因”必须由被引用的来源明确陈述,不得含糊其辞。“可能是由……引起的”映射为unknown。
  5. 信号事实来自普通代码,绝不来自模型:零运行、间隙、峰值、噪声。

数据:真实、公开,且已考虑许可。

  • 遥测:来自 Zenodo 的 OPSSAT-AD,经 md5 校验,CC-BY-4.0。
  • 文档:20 个公开来源(通过 Europe PMC 开放获取 API 获取的基准测试论文、数据集代码、Wikipedia、ESA 页面、新闻转载)被切分为 304 个段落。仅在许可允许的情况下存储全文(CC-BY、CC-BY-SA、MIT);其他所有内容仅保留 ≤300 字符的摘录和一个链接。
  • 时间线:其 11 个条目中的每一个都是逐字引用,在出现之前都会对照存储的文本进行检查。

TabPFN 最佳使用

0.979 → 0.989,且无需训练循环

该数据集上已发表的最先进水平是一个全连接神经网络,其训练、调优和报告发表于Scientific Data于 2025 年。TabPFN-v2 从未在此数据上运行过训练循环。我把训练行和论文自带的 18 个特征交给它,它在官方测试划分上击败了论文。然后我设计了更好的特征,它击败论文的幅度更大。

这就是重点。任务记忆控制台核心的异常检测器不应该需要 GPU、超参数扫描和一周时间。它应该只需要一张表。

Same 18 features as the paper. TabPFN on top.

官方测试划分(529) AUCPR F1 MCC
FCNN,最佳已发表(Sci Data 2025) 0.979 0.946 0.932
TabPFN-v2,论文的 18 个特征 0.989 0.950 0.937
TabPFN-v2,精选特征 0.996[0.989–1.000] 0.982[0.963–0.996] 0.977

方括号为测试片段上的 95% bootstrap 置信区间。

我的目标不是一个漂亮的数字。而是一个我能逐行辩护的漂亮数字。具体方法如下。

1. 先复现论文,再尝试超越它

我下载了 OPSSAT-AD,验证了两个 md5 校验和,并自己清点了所有内容:

  • 2,123 个片段,303,493 个数据点,9 个通道,20.4% 异常;
  • 1,594 个训练片段和 529 个测试片段。

论文正文说 1,494 个训练片段;其自己的表 1 和发布的数据都说是 1,594。

然后我移植了已发表的特征代码。它复现了18 个特征中的 16 个完全一致(占所有值的 99.97%)。在这个过程中,它抓到了我的一个隐蔽 bug:原始文件里有22,115 个重复时间戳,而不稳定的排序会悄悄改变每一个衍生特征。

2. 用程序重新核验基准

我没有用眼睛从 PDF 里抄基准。脚本从 Europe PMC 拉取论文全文(JATS XML),并核对表 3 中的每一个数字。需要超越的门槛是FCNN:AUCPR 0.979,F1 0.946,MCC 0.932(最佳无监督方法:MO-GAAL 为 0.779)。2025 年的更正通知只调整了图表顺序;没有任何表格被改动。

3. 只在训练数据上做所有选择

我在训练集划分上跑了 5 折交叉验证,并按分组方式确保同一通道的相邻片段绝不会跨越折。每个候选特征组都必须证明自己的价值:

Which extra features earn their place? Decided on training data only.

  • 保留:零值连续段与间隙、自相关和稳健离散度,它们共同将 CV AUPRC 从0.9704提升到0.9768。
  • 丢弃:频谱特征和通道身份,它们没有帮助。
  • 集成规模:8 个估计器胜出(CV 0.9781)。

4. 让操作员选择权衡

每个阈值都来自训练集的折外预测,且是在打开测试集划分之前确定的:

  • max-F1为 0.617;
  • 优先在 ≥ 0.80 时,精确率 ≥ 0.95;
  • 队列在 ≥ 0.05 时,召回率 ≥ 0.98。

The queue is a trade-off you choose, from training data.

5. 只运行一次测试集划分

一个守卫会记录每一次测试集运行,并拒绝重复运行同一配置。一次运行:

529 archived segments. 1 false alarm, 3 missed anomalies.

415 个正常片段被正确留在档案中,110 个异常被正确标记,1 次误报,3 次漏报。

6. 在信任之前先检查

相同的划分、相同的特征、相同的折。五个基线和一条启发式规则:

With engineered features, everyone gets better. TabPFN still leads.

官方测试集划分 AUCPR F1 MCC
TabPFN-v2 0.996 0.982 0.977
Random Forest 0.994 0.973 0.966
XGBoost 0.993 0.968 0.960
LightGBM 0.990 0.969 0.960
逻辑回归 0.987 0.956 0.944
Isolation Forest(无监督) 0.401 0.499 0.362
“大量零值或间隙”规则 0.293 0.527 0.414

这是一场胜利,但胜在我的特征上,而不是碾压。好的特征能提升每一个模型。与 Random Forest 相比,TabPFN 是统计上的平局(McNemar p = 0.63;AUPRC 差异 +0.002,95% CI −0.0005 到 +0.006)。与 LightGBM 和 XGBoost 相比,配对 bootstrap 的 AUPRC 差异仅略高于零,而与逻辑回归相比,TabPFN 以 p = 0.03 获胜。

这就是为什么顶部的同口径对比表最重要。在论文自身特征上,TabPFN 比调优后的树模型高出约 0.02 AUCPR,而且论文的神经网络是开箱即用的。

7. 一个名副其实的概率

这个概率是调查队列,所以它必须诚实。测试集上的 Brier 分数:0.0073。

When it says 13%, it means 13%.

8. 我一开始搞错的事

  • TabPFN 拒绝在 CPU 上运行当训练行数超过 1,000 时。Apple 的 MPS 后端反正更快,AUPRC 完全相同。
  • TabPFN 和 XGBoost 在同一进程中加载时会段错误在 macOS 上,因为两个 OpenMP 运行时冲突(退出码 139)。现在它们作为独立的流水线阶段运行。
  • 最新的 TabPFN 权重需要一个账户和非商业许可证。TabPFN v2 无需两者即可下载(Prior Labs License:Apache-2.0 + 署名),所以这里的每个数字都是 v2。
  • 我第一张遥测图绘制出了 553 个“缺口”其实只是降采样造成的伪影。现在缺口只在原始样本上计算。

Tinker 最佳使用奖

65.3% → 93%,花费 83 美分,而且它不再编造了

开箱即用的 Qwen3-8B 会编造频道 ID 并改写引文,而且带着自信的语气,这正是虚假记忆产生的方式。它得了 65.3%。同一个模型、同一个提示、同一个验证器:在花费 83 美分的 Tinker 全包费用后,它得了 93.0%。

我不需要一个对航天器无所不知的模型。我需要一个复制而不是编造的模型,而微调正是小模型学会这一点的方式。

Same model, same prompt, same validator. Only $0.22 of training changed.

基础 Qwen3-8B Tinker LoRA
字段级精确匹配,验证集 65.3% 93.0%[90.7–94.8]
字段级精确匹配,留出测试文档 72.2% 86.3%[83.2–88.9]
频道 ID 正确 70.8% 100%
证据逐字复制自来源 81.1% 100%
“Unknown”使用正确 82.1% 99.8%
整条记录完全正确 0% 44.4%
通过所有检查的调查笔记(任务 D) 56% 100%
被独立验证器捕获的错误 40 0
无支持的根因 0 0

我的目标不是最大的数字。而是一个我能以最低价格辩护的真实数字。以下就是具体做法。

The fine-tuning pipeline

1. 在任何训练之前冻结指标

在任何模型看到任何数据之前,我冻结了核心指标:留出文档上的字段级精确匹配,在任何修复之前对原始输出评分。配套指标:

  • 有效 schema 率;
  • 逐字证据率;
  • 无支持根因计数;
  • “unknown”的正确使用;
  • Wilson 置信区间;
  • 针对基础模型的配对 McNemar 检验。

2. 在缩小模型之前,先缩小账单

Tinker 按 token 计费,因此输出是 8 行紧凑内容,代码会将其转换为 Pydantic JSON:

channel_id: CADC0873
sensor_type: magnetometer
units: ?
event_date: 2024-05-22
observation: On 22 May 2024 the magnetometer I_B_FB_MM_1 reported a run of zero values.
operational_response: ?
root_cause: ?
evidence: On 22 May 2024 the magnetometer I_B_FB_MM_1 reported a run of zero values.

一个完整的训练示例,包含提示词和段落,大约为380 个 token。

3. 为各个选项定价,再做选择

每百万 token 的训练费用:

  • Qwen3-8B:$0.44。
  • Qwen3.5-4B:$0.737。更小的模型并不自动意味着更便宜。
  • GPT-OSS-20B:$0.396,但它是一个推理模型,其思考 token 在采样时会花费更多,并会破坏格式。

4. 训练:rank-16 LoRA,仅对答案计算损失,5 分钟

renderer = renderers。get_renderer("qwen3_disable_thinking", tok)
mi, w = renderer。build_supervised_example(messages, train_on_what=TrainOnWhat。LAST_ASSISTANT_MESSAGE)

fb = tc。forward_backward(batch, loss_fn="cross_entropy")
op = tc。optim_step(tinker。AdamParams(learning_rate=lr_t, beta1=0.9, beta2=0.95, eps=1e-8))
  • 数据:四个任务(抽取、时间线、带引用的术语、调查笔记)的示例。
  • 调度:batch 16,线性学习率衰减,3 个 epoch,每个 epoch 保存一个检查点。最终运行耗时5.1 分钟。
  • 按文档族划分,绝不按块划分:测试文档(基准测试论文加 Wikipedia)从不出现在训练中,而该论文的 arXiv 预印本在所有地方都被排除,因为它是近似重复项。
  • 预算保护:它根据本地 token 计数为每个作业定价在提交之前,并拒绝任何超过上限的作业。我从$0.93开始。

5. 65.3% → 93.0%:找到曲线的拐点

我没有只训练一次然后祈祷。我分阶段训练,在同一个验证集上为每次运行打分,并为每次运行定价:

65.3% → 93.0%. The first 2.5 cents did most of the work.

运行 预估成本 验证字段完全匹配
基础 Qwen3-8B,未训练 不适用 65.3%
运行 1 $0.025 90.8%
运行 2 $0.049 91.8%
运行 3 $0.097 92.2%
最终模型 $0.224 93.0%

前 2.5 美分的训练将模型从 65.3% 提升到 90.8%。之后的每次运行又增加约一个百分点,最终模型达到93.0%,全部在 83 美分的预算之内。

6. 验证错误分析发现了我的bug

中途,大多数剩余的“错误”是模型正确地拒绝引用代码块、脚注和 markdown 项目符号列表,而我的标注规则将这些选为了“观察项”。

  • 我将规范收紧为仅限散文句子。
  • 我终止了一次半途而废的运行而不是花钱在糟糕的标签上把它做完。
  • 我重新训练了一次。
  • 测试集全程保持封存。

7. 这个提升是真实的还是噪声?

逐单元格配对,在相同的 576 个字段单元格上:95 个单元格只有微调模型做对了,14 个只有基础模型做对了。精确 McNemarp = 5.8×10⁻¹⁶。

It stopped inventing channel IDs and started quoting sources.

基础模型的40 次校验器捕获正是校验器的用途所在:源中不存在的通道 ID 和引文。微调模型一次都没有。即使在校验器修复基础模型的输出之后,它也只达到 78.5%,仍低于微调模型的未修复86.3%。

8. 租用训练。保留权重。

我把适配器导出为 PEFT(一次张量重命名:unembed_tokens→lm_head),用 llama.cpp 将其转换为 GGUF,并在 Q4_K_M Qwen3-8B 基础模型上运行:

在留出段落上字段精确匹配率 92.5%,与 Tinker 上同一检查点逐字段一致率 100%,每段 4.7 s。M3 Pro,18 GB,Hugging Face 离线,环境中没有 Tinker 密钥。

全部账单

Where the $0.83 went. Everything on Tinker.

项目 预估成本
学习曲线运行(第 1–3 次) $0.17
在发现标签错误后于 65/84 步停止的一次运行 $0.17
最终模型(3 个 epoch) $0.22
可下载的兄弟适配器(见已知边界) $0.10
Tinker 上的全部评估 $0.17
Tinker 上的全部开销 $0.83

按 Tinker 标价计算的 token 数,在每个作业前记录。基础模型验证在本地免费运行。


已知边界(实测,未隐藏)

我更希望这些是你从我这里听到的,附带数字。

  • 我没达到自己的目标。我在训练前设定了95%。模型在验证集上得到93.0%,在测试集上得到 86.3%。大部分差距来自一个判断取舍:在不熟悉的文档中,哪一句是“观察结果”。
  • 微调让一个任务变差了。为遥测术语引用正确来源的比例从96.2% 降至 82.7%(p = 0.016)。该任务的训练数据最少,而微调后的模型学会了过于急切地回答“不在档案中”。
  • 离线适配器是一个兄弟版本。Tinker 不允许你下载采样器检查点,而我的最终运行只保存了这些。因此离线适配器是一个更小的兄弟配置,用可下载的检查点重新训练(验证 92.3% 对 93.0%)。训练脚本现在会保存两种。
  • 标签是规范,不是人工标注。“精确匹配”意味着在未见过的文档上与确定性规范保持一致。有些字段(单位、操作响应)只出现在少数几个留出段落中。
  • 验证器拒绝了我自己的模型。在演示中,6 个中的 4 个调查卡片回退到了确定性文本。在其中一张卡片里,解释器写道根本原因“有文档记载”,这与其自己的 NOT KNOWN 列表相矛盾。守卫机制抓住了它。我宁愿展示一张朴素的卡片,也不愿展示一张自信但错误的卡片。
  • 在我工程化的特征上,TabPFN 相对 Random Forest 的优势在统计上是平局。它明确的胜利是在同等条件下、使用论文的特征取得的。

过程中出了什么问题(以及如何变得更好):我的基座模型对比起初并不公平。提示词从未点名那八个字段,解析器又拒绝 markdown,所以我在训练任何东西之前把两者都修好了。一条根因规则一度把“由于任务本身的底层性质”当作原因,还有一处 Q&A 排序调整让一个答案更漂亮,却悄悄从其他答案中移除了“原因未知”的警告。两者都被发现并回滚了。

为什么开放创新很重要?

封闭 API 给你一个答案。开放权重和开放数据给你一种核查它的方式。对于一个整个工作就是拒绝编造记忆的项目来说,这种差别就是一切。

开放具体在哪些地方胜过封闭:

我需要的 封闭 API 开放让我做到的
阻止模型编造频道 ID 写更长的提示词然后祈祷 微调权重:编造的 ID 降至零,花费 $0.22
信任异常概率 相信厂商的说法 我自己在公开测试集上测量校准(Brier0.0073)
击败已发表的基准测试 无法验证 精确复现论文的特征,然后在同等条件下击败它
在热度过后继续运行 取决于厂商是否持续运营 适配器 + TabPFN 在笔记本电脑上离线运行,无需密钥,无需计量

那张表背后的原因:

  • 我可以审计存档。数据集作者公开了数据和特征代码,所以我精确复现了他们的特征,并发现他们划分计数中的一个笔误。一个可以事实核查的鬼故事是另一种故事。
  • 我可以改变模型,而不只是提示词。基座 Qwen3-8B 编造了频道 ID。22 美分的 LoRA 训练阻止了它。
  • 我可以测试概率。借助 TabPFN 的权重和公开测试集划分,我自己测量了校准度(Brier 0.0073),而不是相信别人打印出来的数字。
  • 没有计时器在跑,也没有人会把它弃用。适配器和 TabPFN 运行在存放档案的那台笔记本电脑上。航天器消亡之后,它的记忆不应依赖于别人的 API 是否还在运行。
  • 记忆应当是一种公共资源。OPS-SAT 之所以存在,是因为 ESA 向外部者开放了一颗卫星。它的记忆也应当同样开放。

诚实的提醒:训练在 Tinker 的服务器上运行,且仅使用公开文档。运行时,没有任何数据离开这台笔记本电脑。

我的智能体会话

我与Claude Code作为搭档一起构建了 The Last Satellite,依据一份书面的 12 小时计划,计划事先包含成本估算,对每个 Tinker 任务设有预算守卫,对每次测试集运行也设有守卫。

  • 它在写代码之前先阅读了来源资料。它阅读了 Tinker 和 TabPFN 的文档,从全文重新核验了论文的基准测试表,并在移植之前阅读了原始特征代码。
  • 它抓住了自己的错误:
    • 一个重复时间戳的排序 bug;
    • 一个不公平的基座模型提示词;
    • 通过验证误差分析发现的标签 bug;
    • 一条过于宽松的根因规则。
  • 当数据表明应当停止时,它停止了花费。它在标签有问题时终止了一次进行到一半的运行,而当最终检查点被证明无法下载时,它先询问我,然后才花掉我最后的额度。
  • 它回退了自己的“改进”当这项改进使诚实性保证变差时。
  • 它维护了一份持续更新的成本账本从第一个任务开始。

奖项类别

最佳 TabPFN 应用。TabPFN 是控制台的引擎,而非附加组件:每一个概率、每一个队列位置以及每一个“实测最佳特征”都来自它。

  • 官方 OPSSAT-AD 测试集划分,一次记录在案的运行: AUCPR 0.996,F1 0.982,MCC 0.977,对比已发表的最佳成绩0.979 / 0.946 / 0.932。
  • 在论文自身的 18 个特征上,无需训练循环: 0.989 / 0.950 / 0.937,超过了论文以及调优后的树集成模型。
  • 严谨性:经过校准(Brier 0.0073),阈值仅在训练数据上选择,并与五个基线进行比较,采用 bootstrap 置信区间和 McNemar 检验,包括我对自己报告的那次平局。

最佳 Tinker 应用。LoRA 微调(仅对答案计算损失,按 epoch 保存检查点)、学习曲线、预算保护、带配对统计的留出评估,以及离线故事背后的适配器下载,全部在 Tinker 上运行。最终模型花费 $0.22,全部花费 $0.83。

  • 相同的基座模型、相同的提示词、相同的验证器:抽取65.3% → 93.0%在验证集上(72.2% → 86.3%在留出测试文档上),逐字证据81% → 100%,调查笔记56% → 100%,以及0 个凭空编造的根因。

独自一人用 Claude Code 构建,历时一个漫长的万圣节之夜,在亡灵节开始之际完成。

两个开源模型。八十三美分。一条规则:要么测量它,要么引用它,要么称其为未知。如果这听起来像是纪念一颗卫星的正确方式,一个 ❤️ 或 🦄 能帮助更多人发现它。

这个亡灵节,为你爱过却已逝去的一台机器点一支蜡烛:一部旧手机、第一台笔记本电脑、一台运行了十年的服务器。你希望它的档案记住什么?留在评论里吧。🕯️