跳转至

2025 年

24 岁,站在人生的十字路口

2025 年 10 月 9 日,我按下发送键,将辞职信发给了领导。那一刻,我在人生的十字路口转了个弯。

一年多前刚毕业的我,大概想不到自己会在一年后选择离开公司,甚至离开陪伴了我数年的量化行业。从 2020 年接触量化开始,到实习、全职工作至今,我曾经期待过自己会在这条路上一直走下去。

改变并不是某个瞬间的决定,而是一个缓慢的积累过程。一些念头在心中生长得很隐秘,最初只是微弱的疑问,后来逐渐变成了无法忽视的声音。我想在 24 岁的十字路口,用这篇博客记录下这场重要的“改变”——记录我走过的路,也记录路上遇到的那些珍贵的人和事。

illustration


大模型结构化输出的作用、技术原理与实现

大语言模型(LLM)具有强大的文本生成能力,可以输出易于人类阅读的自由格式文本。但是,这一生成过程是概率性的,而不是确定性的。当我们在复杂的软件系统中使用 LLM 作为工作流的一部分时,我们可能需要确保 LLM 的输出符合一定的格式和类型等规范。例如,如果用 LLM 进行文本二分类,我们可能只需要得到  True  或  False  的布尔值,而不希望得到其他任何文本,这就要求 LLM 的输出是严格结构化的。

结构化输出(Structured Output)技术可以解决这一问题,它确保 LLM 的输出严格遵守预定义格式和约束,从而极大地提升 LLM 在自动化工作流和程序化集成中的可靠性。LLM 有了结构化输出的能力后,就能从一个“对话工具”变成一个靠谱的“数据提供者”。

本文讨论了大模型结构化输出的作用,以及实现结构化输出的一些原理和技术实现方案。

技术路径 实现原理 成本 可靠性 适用场景
提示词导向生成 依靠 Prompt 中的软规则与示例,让模型“自觉”输出符合格式的文本。 极低 低~中:模型可能偶尔多输出解释或漏字段。 快速原型、轻量级应用、对格式要求不严的辅助任务。
自动验证与修复 模型生成后先做结构校验;如不合规,系统自动带着错误信息重新请求模型修正。 中:能兜底一次又一次修复错误,但仍非绝对稳固。 需要容错但又不想写硬约束的生产系统,如数据抽取、轻量级结构化任务。
约束解码 在 token 级生成的每一步实时过滤非法 token,用 JSON Schema/CFG/FSM 硬性约束生成路径。 中~高 极高:能从源头保证输出完全合法。 对格式要求极严格的任务,如复杂 JSON、代码生成、严苛 API 指令。
草图引导 / 外部精炼 黑盒模型自由生成草稿,再用可访问 logits 的本地模型按语法规则精炼修复。 中~高:依赖草稿质量,但最终输出能较好满足约束。 黑盒模型不提供 logits 时的 JSON/DSL 生成,本地自动化管线。
NL→Format 两阶段生成 模型先自由推理完整答案,然后再将自然语言结果转换成结构化格式。 中~高:推理质量好,格式化环节仍可能需轻微兜底。 推理复杂但格式规则简单的场景,如 Agent 思考链、任务规划。
监督式微调 用大规模样本直接把结构化输出范式“教进”模型参数中,形成稳定风格。 高:数据质量足够好时,模型能持续稳定地产生结构化格式。 金融/医疗/法律等需要长期稳定抽取的领域任务。
强化学习优化 通过奖励模型给输出提供细粒度反馈,优化模型在结构与内容上的决策路径。 极高 极高:在复杂推理、深层结构生成等方面最稳定。 多步骤推理、复杂 JSON、深度嵌套结构、需要持续优化策略的场景。
原生 API 结构化输出能力 服务商在 API 内部使用约束解码与安全机制,直接保证返回严格的结构。 低~中 极高:由 API 层完全托管,开发者不再接触底层复杂度。 商业应用、智能体工具调用、生产级数据接口。

为什么注意力机制中要除以 \(\sqrt{d_k}\) :从方差到梯度的推导

\[ Attention(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V \]

在 Transformer 的注意力机制中,计算点积注意力 \(QK^T\) 之后,需要除以一个 \(\sqrt{d_k}\) 进行缩放。这一操作通常被解释为“为了数值稳定性”。这里的“稳定”究竟指的是什么?如果不除以 \(\sqrt{d_k}\) 就不稳定了么?为什么不除以 \(d_k\) 或其他数值呢?

本文分析了点积的方差如何随维度增长而增大,并进一步推导 \(\text{softmax}\) 变换得到的行向量的雅可比矩阵,展示当输入数值过大时梯度如何逐渐趋近于零。通过这一过程,我们将会理解,除以 \(\sqrt{d_k}\) 并不是随意的设置,而是确保注意力机制在高维空间中仍能保持可训练性的必要条件。

Docker 中的 CMD 和 ENTRYPOINT

Docker 中的 CMD 和 ENTRYPOINT 都是用来指定容器启动时执行的命令,但它们的作用和使用场景有明显区别,理解它们的区别能帮助我们更灵活地控制容器行为。

CMD 和 ENTRYPOINT 的通俗理解

  • ENTRYPOINT:就像容器的“主菜”,是容器启动时必须执行的命令,无论启动容器时传入什么参数,这个命令都会执行。可以把它想象成披萨店的“披萨”,披萨是必做的主食。
  • CMD:就像披萨的“默认口味”,是容器启动时的默认参数或命令,如果启动容器时没有指定其他命令,CMD 会生效;如果指定了其他命令,CMD 会被覆盖。它是给 ENTRYPOINT 提供默认参数,或者单独作为默认命令使用。

  • 如果只有 CMD,启动容器时指定的命令会替代 CMD。

  • 如果只有 ENTRYPOINT,启动容器时的参数会附加到 ENTRYPOINT 命令后面。
  • 如果两者结合,ENTRYPOINT 定义主命令,CMD 定义默认参数,启动时可以覆盖 CMD 参数但不会替换 ENTRYPOINT。

pandas rolling exponential 滚动计算指数加权标准差会受起点影响

在使用 rolling(win_type="exponential").std() 计算标准差时,结果可能会受数据起点的影响。

本文将通过几个简单的代码示例,探究数据具有不同数据起点(通过 iloc[1:] 手动构造不同的数据起点进行模拟)对 Pandas rolling(win_type="exponential").std() 计算结果的影响,并提供了一个自定义函数实现严格控制滚动回看窗口,以获得一致的结果。