Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

从零开始理解强化学习的模型训练

Posted on 2025-08-11

对 RLHF、TRPO、PPO、GRPO、DPO 和 RLAIF 的直观处理

在本文中,我们将讨论在法学硕士 (LLM) 的背景下,强化学习模型训练 (RLMT)。我们将从能够预测下一个标记的预训练模型入手,逐步讲解将其训练成指令调优模型所需的一切。在上一篇题为“ 利用中学数学从零开始理解法学硕士 (LLM) ”的文章中,我们使用基本的数学运算符从零开始构建了一个大型语言模型。这篇文章内容完整,只需要中学数学知识即可阅读,而且阅读量很高,成为 2024 年媒体的热门文章之一(能够与巴拉克·奥巴马这样的作家一起发表真是太棒了)。因此,我假设大家喜欢这种实事求是、不带任何术语、从第一性原理理解一切的方法。我们将在这里采用相同的方法,但有两点变化:

  • 本文将与上一篇文章形成一个完整的框架,但其本身并不独立。这意味着我不会重复上一篇文章的内容,并且我们假设你已经了解什么是法学硕士 (LLM)。
  • 我们假设你具备一些高中知识。基本上,我们假设你知道什么是变量,什么是向量,什么是概率,以及 \Sigma 符号表示加法。

让我们开始吧。我们之前提到的模型,是经过训练的,可以预测英语中下一个词条。为了简单起见,我们将词条视为一个单词,因此,该模型的作用是,如果你输入一些文本,它会尝试预测最有可能的单词作为该文本的延续。这些模型被称为预训练模型,例如 GPT 和 Llama。

虽然这看起来像是美化过的自动完成功能,但预训练模型实际上可以完成非凡的事情。例如,如果我尝试完成句子“德国的首都是”,模型会用“柏林”来补全它。此外,你可以将文本递归地反馈给模型,让它写出更长的文本和文章,如图 1 所示。例如,你可以先给模型输入以下文本:“本文探讨了佛罗里达的鳄鱼,涵盖了它们的栖息地、身体特征、饮食、繁殖、与人类的互动以及一些有趣的事实。” 继续输入这段文本,一个优秀的预训练模型就能完成整篇关于佛罗里达鳄鱼的文章,以及种子文本中提到的方面。

图 1:将生成的标记递归地输入到 LLM 中,以生成更长的文本

此时,你可以想象,任何你想让模型做的事情都可以重新定义为完成目标,例如“这是一篇关于……的1000字论文”,而不是“给我写一篇关于……的1000字论文”。那么,我们为什么需要指令调整模型呢?

指令调整模型

有效地将预训练模型用于实用目的需要改变行为,这很困难。另一方面,指令调整模型可以用于自然的问答形式,从而提高易用性和采用率。这一点从 LLM 在第一批指令调整模型面世后真正流行起来就可以看出。

作为文本补全模型,预训练模型会尝试根据训练数据语料库预测最可能的下一个标记。这意味着预训练模型可以:

  • 由于训练数据可能包含问题列表,因此用附加问题来回答问题
  • 没有很好地遵循指示
  • 编造看似合理但实际上并不存在的事实或名称/地点
  • 不加思索地生成攻击性或有害内容

微调过程通常用于进一步训练模型以解决这些缺陷。这带来的最大可见变化是模型能够遵循问答格式的指令,因此我们将这些模型称为指令调整模型(IT 模型),例如 Ouyang 等人 (2022)、Thoppilan 等人 (2022)、Touvron 等人 (2023)。

现在,我们如何让模型回答问题?我们能想到的最简单的方法是,如果模型是基于问题后跟答案的数据进行训练的,那么它就会学会以某种方式进行文本补全,从而用答案完成问题。本质上,模型没有任何变化,只是现在它被更强烈地训练去完成任何带有答案的问题文本。这是指令调整的关键。

然而,这并不能让我们完全达到我们想要的效果。例如,如果你现在在任何法学硕士课程中输入“短吻鳄和鳄鱼”,它会给出对这两种动物的描述以及它们的异同。如果这些仅仅是文本补全,那么预期应该是以某种合理的方式延续句子,而不是将其视为问题并尝试返回答案。这是如何实现的?一种简单的方法是构建模型中的训练数据,使问题以“用户”开头,答案以“模型”开头。就像这样:

  • 用户:什么是羚羊?模型:羚羊是牛科的一种哺乳动物……
  • 用户:蜘蛛有几条腿?模型:蜘蛛有八条腿……
  • 用户: 《罗密欧与朱丽叶》是谁写的?模型: 《罗密欧与朱丽叶》这部标志性的爱情悲剧,作者是……

通过以这种方式在训练数据中构建问题和答案,每当模型看到“User:”后跟一段文本,再接着“Model:”时,它就会被训练成将该文本视为一个问题,并用看起来像与该文本相关的完整答案的内容来完成整个序列。这在本质上类似于欧阳等人(2022)提出的聊天标记语言。

这种方法效果相对较好,但可能存在问题。例如,如果字符串 User: 或 Model: 自然出现在问题或答案中,例如“分隔符 ‘User:’ 通常如何在模型训练中使用?”,这是一个可以向法学硕士 (LLM) 提出的有效问题。我们可以改进这个系统吗?让我们回到文本如何输入这些神经网络的基础知识。记住,神经网络只能摄取和输出数字。因此,所有文本都被分解成子字“标记”,然后输入到网络中。每个标记都由一个向量表示,该向量是它的“嵌入”。因此,本质上,当你将文本输入到 LLM 时,你真正输入的是一系列向量,每个向量代表一个标记。如果这感觉不熟悉,你可能需要回顾一下使用中学数学从头开始理解 LLM 。

将问题与答案区分开来的一个好方法是简单地铸造两个新标记(和相应的嵌入向量),将它们放置在 User: 和 Model: 的位置。这类似于发明一个新字符来分隔文件,因为所有现有字符可能已经存在于某处。为了方便起见,我们将这些新铸造的标记称为 <USER> 和 <MODEL>。这并不意味着字符串 <USER> 和 <MODEL> 对模型具有特殊含义 – 我们只是在纸面上使用它们来表示特殊标记,因为我们需要某种方式来表示它们。实际上,如果有人将这些字符串提供给模型,它们会有自己的标记化,就像其他任何东西一样,例如 <THISSTRING> 或 <THATSTRING> 等。这些标记仅表示分隔符(我们可以将它们称为 <DELIM1> 和 <DELIM2>,除了在本讨论中之外,在其他任何地方都没有任何区别)。使用这种新方案,可以训练嵌入,并且现在可以让模型始终在特殊标记后使用答案类型补全。现代的 intstruct 调整模型使用了 Askell 等人 (2021) 提出的该方案的一些变体。

现在,我们已经有了一个相当不错的方案,可以指导如何调整模型,并确保文本补全模型的行为越来越像问答模型。如果我们能够设计一个优秀的问答语料库,那么使用相同的下一个标记预测方案对模型进行额外的训练就能达到我们所需的效果。此外,这个阶段现在可以用来在模型上强制执行我们感兴趣的其他值。例如,我们可以:

  • 在训练数据中放入问题,并附上具体的说明和遵循这些说明的答案,这样模型就可以更好地遵循答案中的说明
  • 在回答中提出可能导致有害或冒犯性内容的问题,然后拒绝回答,以便模型学会拒绝回答可能有害的问题(例如,当被问到“如何制造脏弹?”时回答“抱歉,我无法提供该信息”)。

这些并非训练过程中可以解决的全部问题。此外,上述遵循指令和负责任的人工智能的目标通常需要多种方法的结合才能实现,而不仅仅是本文所描述的方法。

监督微调

监督微调与预训练并无二致。在这两种情况下,你做的事情完全相同,即训练模型预测下一个标记(当然也存在其他目标,例如 Devlin 等人 (2019) 中使用的掩码语言模型,但这些模型并不那么流行,也超出了本文的讨论范围)。关键区别在于,在预训练期间,你使用的语料库要大得多,例如常见的爬虫文本;而监督微调 (SFT) 则使用规模小得多且质量更高的数据集。另一个实现细节是,在预训练期间,我们将所有训练数据连接成一个(非常长的)文本,然后按上下文长度进行拆分,以最大限度地提高训练效率。在进行监督微调时,每个样本都被视为其独立的样本,我们会填充较短的样本,并截断较长的样本,以匹配长度,使它们都等于训练上下文的长度。

由于上一篇文章中没有写,我们先把下一个 token 预测目标的损失函数写下来。假设我们有一个词汇量为 32,000 的 LLM。这意味着 LLM 的输出层将包含 32,000 个数字。在上一篇文章中,我们讨论了 softmax 函数及其背后的原理。应用 softmax 函数后,我们得到 32,000 个介于 0 到 1 之间的数字,它们加起来都为 1,因此可以将其视为 32,000 个 token 的概率向量。我们用索引变量来命名这 32,000 个数字,第一个数字为 p_1,第二个数字为 p_2。 依此类推,使得iᵗʰ数字从p_i一直到 p_32000。

现在,在下一个标记预测案例中,我们有了训练数据。假设句子“The quick brown fox jumps over the lazy dog”是我们训练数据的一部分。所以我们在这里做的是,如果我们给模型输入文本的一部分,比如“The quick brown fox”,那么模型应该预测“jumps”。这意味着在词汇表的所有32k 个标记中,标记“jumps”的概率应该最高。在实践中,标记与单词不同。单词通常被分解成一个或多个标记。例如,单词 jumps 可以分解成两个标记。为了便于理解,我们假设我们的语言模型使用单词作为标记。假设 jumps 是iᵗʰ标记,那么我们想要做的是最大化p_i 。

现在,每个 p_i 的值会根据之前输入的标记而有所不同。例如,如果我们现在将“The quick brown fox jumps”输入到网络,我们希望最大化另一个 p_j,其中jᵗʰ标记表示“over”。我们需要一些简洁的方法来表示这一点。基本上,我们想要捕捉的是在将“The quick brown fox”输入到模型的条件下“jumps”的概率。并且我们希望能够轻松地用许多单词来表示这一点。让我们将句子中的所有标记标记为 tok_1、tok_2、tok_3 等等。

让我们使用向量文本来表示包含T个标记的标记向量,即tok_1, tok_2…tok_T 。重复写出所有标记会很累,所以我们使用符号a_t来表示tok_t ,使用s_t来表示tok_1, tok_2,…,tok_{t-1},这将使我们更容易表达。注意,s_t计算的是前t-1 个标记,而不是前t 个标记。让我们用π来表示事件的概率。让我们用 ‘|’ 来表示“条件”。所以我们可以将上述概率写成:

现在,如果我们希望模型学习整个句子,我们将递归地预测这些概率。如果我们假设它们是独立的,我们可以将这些概率相乘,得到模型生成序列的总概率。因此,目标是:

这些概率数非常小。对于其中的每一个,概率都是 32k 个数字中的一个,这些数字加起来都等于 1。所以你实际上是在乘以并最大化非常小的数字。如果所有概率都相等,它们将是1/32000 = 0.00003125 ,因此很多数字都会更小。即使对于像这样的小序列,将它们相乘也可能意味着你试图最大化的数字大约为(1/32000)⁹ = 2.84 × 10⁻⁴¹,其中小数点后和数字 284 之前有 40 个零!这是一个很难处理的数字。幸运的是,如果我们取对数,则log(1/32000) = -10.37 ,这似乎是一个更容易管理的数字。此外,对数函数还有一个很棒的性质: log(a·b) = log(a)+log(b) ,所以如果我们对这些表达式取对数,不用把非常非常小的数相乘,得到更小的数,而是直接把几个大小合适的数相加即可。由于对数函数是一个良好的单调函数,最大化x和最大化log(x)是同一个意思。那么,我们为什么不换一种更易于理解的方式来写我们的目标函数呢?

现在我们有了几个合适的数需要最大化。记住,所有对数都为负数,因为任何小于1的数的对数都是负数,而所有概率都小于1。因此,最大化一个负数意味着你正在最小化它的幅值,因为在实数轴上-5大于-10。一个简洁明了的选择是将问题改写成一个带负号的最小化问题。这样,你就得到了需要最小化的正数。此外,并非所有序列的长度都是9,所以我们将其设为一个更通用的T长度序列。

在这里,你真正做的是在最小化损失的同时改变模型的参数,所以这些概率会改变。如果我们想要真正清楚,我们应该在损失函数的某处添加说明,说明它来自特定的模型。一种方法是简单地将模型置于条件中,这样你真正要说的就类似于将“The quick brown fox”输入到模型中时“跳跃”条件的概率,其中模型是 M 。让我们用NLL(text,M)来表示损失。这会使损失看起来像这样:

所有的数学符号可能让它看起来很复杂,但正如我们所知,它其实相当简单。我们只是试图最大化模型中特定标记的概率。这个公式也被称为“负对数似然”,因为模型下标记的概率也可以被认为是模型在给定标记的情况下的似然值。给出更好概率值的模型更有可能是一个更好的模型。所以你可以说你正在最大化似然函数,并试图找到一个能给出最大似然函数值的最佳模型。我们已经讨论过,一旦有了损失函数,我们就可以如何使用梯度下降来最小化损失。监督微调就是用负对数似然作为损失函数来实现这一点的。这种损失也是预训练中使用的,只是规模要大得多。 NLL 损失在深度学习文献中也被称为“交叉熵损失”,这恰好是一个更通用的概念,我们在《负对数似然、交叉熵、KL 散度和重要性采样的直观处理》中进行了讨论。Fisher (1922)、Kullback 和 Leibler (1951)、Shannon (1948)、Hopfield (1987) 和 Bengio 等人 (2003) 奠定了其中一些基础。

最后需要注意的是,上面写的损失是针对单个样本的。通常,训练时会用到大量的训练样本来进行监督微调,并对所有这些样本取平均损失。假设将所有训练样本的集合表示为S ,并假设集合S中有S 个样本;那么损失看起来就像这样:

需要注意的是,文本是特定样本的问题和答案的串联。这也意味着,如果我们想让模型简单地学习如何生成问题的答案,我们可以从 token t开始计算 NLL,其中t是答案的第一个 token。除了 NLL 定义的细微变化外,这不会改变我们上面讨论的任何内容。

因此,我们已经准备好使用 SFT 对模型进行指令调优,但现在的问题是找到一个涵盖广泛主题的问答对语料库。文字世界充斥着书籍、文章、论文等,但问答形式的文本却远远不够。一种选择是让人类编写问答,或者从其他地方获取问题(例如用户在线提问),并让人类编写答案来补充任何可以在线找到的问答数据集。所有这些方法都耗时且成本高昂。尽管如此,SFT 仍然是训练模型进行指令调优并使其达到相当不错的答案生成水平的关键第一步。

拒绝抽样

我们的模型现在可以在一定程度上回答问题了。我们可以做些什么来扩展训练并使其变得更好呢?一个想法是,我们可以利用模型本身来生成更多的问答数据。如果我们可以从某个地方获取问题,并让模型生成答案,我们就能得到更多的问答对。这将大大减少创建此类数据集进行微调的工作。然而,问题在于,由于模型训练不充分,它可能无法生成最佳数据。我们该如何解决这个问题?

我们何不尝试用模型为每个提示生成多个答案,看看其中是否有一些答案是好的,从而有效地剔除所有其他答案?这样我们就能整理出一个比平均模型答案质量更高的模型生成数据集。此外,人们从一组答案中挑选出最佳答案比手动输入一个好的答案要容易得多。整个过程大致如下:

  • 从提示开始
  • 使用当前模型为该提示生成 G 个不同的完成(响应),通过以足够的随机性(温度)进行采样来获得多样性。
  • 对 G 响应进行排序。
  • 选择最佳回应(或最佳少数回应)并丢弃其余回应。
  • 对提示上的模型进行微调,并将其与选定的最佳响应配对,将其视为 SFT 数据。

我们现在有一种方法可以使用模型生成用于监督微调的数据集。这是一个模型生成的数据集,但尽管如此,我们还是会用它来使用 SFT 来训练模型。

我们如何进一步改进?虽然人类更容易从样本中找到好的答案,但这仍然是一个手动过程。如果我们有一个模型来挑选更好的答案会怎么样?我们可以训练一个“偏好模型”,当提供两个选项时,它能够从两个答案中选择更好的答案。我们仍然需要人工标注的数据来训练这个偏好模型,但在完成最初的人工标注工作后,我们就能够使用偏好模型引导一个自动化流程。为了训练这个偏好模型,我们需要包含提示和两个生成的答案的数据,其中人类已经选择了偏好的答案。本质上,你有两个text_i 和 text_j,它们分别是提示和生成的答案之一的组合。令hp表示数据中记录的实际人类偏好, hp可以取值 0 和 1,如果hp=1 ,则text_i就是人类偏好的文本。该模型接受两个文本输入,并输出每个输入被人类偏好的概率(即,它返回第一个输入被人类偏好的单一概率,我们称之为P(text_i) ,因为另一个概率将简单地为P(text_j) = 1-P(text_i) )。现在我们想要做的是在hp=1时最大化P(text_i) ,在hp=0时最大化P(text_j) 。我们可以使用上面相同的技巧将概率转换为负对数似然并将其转化为最小化问题,从而写出损失:

因此,当人类偏好hp=1时, P(text_i)最大化;当hp=0时, P(text_j) = 1-P(text_i)最大化。这与之前相同,并且以同样的方式,为了获得平均损失,我们只需对训练数据集中的所有提示取平均值即可。此损失函数称为“二元交叉熵损失”。拒绝抽样的一般概念是由冯·诺依曼 (1951) 提出的,而 Zelikman 等人 (2022) 和 Yuan 等人 (2023) 展示了其在 LLM 训练中的应用。我们也可以将text_w表示为获胜文本,并简化表达式:

剔除采样,然后在近乎自动化的循环中进行监督微调,听起来像是一种改进模型的好方法。但它也存在一些问题和需要改进的地方:

  • 离散学习:当我们进行拒绝抽样时,我们会以离散的步骤进行学习,即对大量问题进行大量响应采样,然后进行一轮改进后的SFT。这意味着我们会使用拒绝抽样数据执行多次参数更新。
  • 无法从错误中学习:当我们丢弃不良输出时,模型并不会学习它们为什么不好。它只会从最佳答案中获取“它是好的”信号。如果模型在被丢弃的样本中反复出现某种错误,该方法不会明确惩罚该错误。反馈纯粹是正面的(针对所选答案),而不是负面的(针对其他答案)。本质上,模型不会被告知什么不该做,只会被告知应该多做什么。这可能会限制改进,或者需要大量样本才能让模型隐式地找出不良响应的界限。
  • 高计算成本:为每个提示生成大量样本的成本很高,尤其是对于大型模型而言。如果我们为 10 万个提示中的每个提示生成 10 个候选样本,则需要 100 万次模型前向传递才能筛选出 10 万个最佳样本。这比每个提示单次传递要耗费更多工作量。有时可以通过并行生成或巧妙采样来缓解这个问题,但这仍然是一个需要考虑的因素。
  • 模型崩溃与偏差:这是拒绝采样最重要的问题。如果我们总是根据固定标准选择得分最高的答案,就有可能在该标准上过度优化模型。模型可能会开始给出非常狭窄、经过优化的答案,这些答案得分很高,但缺乏多样性甚至连贯性。例如,如果奖励模型或人工注释者无意中偏爱冗长的答案,模型可能会收敛到总是给出过长的答案。在极端情况下,模型可能会利用评分系统的弱点,这种现象类似于奖励黑客攻击。没有任何平衡,反复对顶部输出进行微调可能会导致模型分布在评分者喜欢的模式附近崩溃,即使这些模式并非自然。我们可能会将模型推入评分模型未得到良好校准的区域,导致评分者错误地给出高分的垃圾输出。“不从错误中学习”需要进行多轮拒绝采样,然后进行SFT,这增加了模型崩溃的可能性,从而使这个问题更加严重。

强化学习

我们如何才能比拒绝抽样做得更好?让我们尝试解决上面列出的问题。本节的大部分内容将讨论强化学习方法,这些方法由 Brown (1951)、Bellman (1957)、Barto 等人 (1983)、Sutton (1988)、Watkins (1989)、Littman (1994)、B¨orgers 和 Sarin (1997)、Hu 和 Wellman (2003) 以及其他许多人开创。但是,我们将在 LLM 训练的背景下讨论它们。在强化学习文献中,在给定当前s_t 的情况下确定a_t值的规则集称为“策略”, a_t被称为时间t 时的“动作”,而s_t被称为时间t 时的“状态”。本质上,策略就是在当前状态s_t (在我们的例子中,当前状态是字符串,即到点 t -1 的标记)的情况下,为动作集合(在我们的例子中,动作集合是模型词汇表,而最终 softmax 层的输出是概率分布)提供概率分布。然后,你从这个概率分布中采样动作a_t 。例如,你可以简单地将概率最高的标记作为a_t (这称为贪婪解码)。在我们的例子中,模型就是策略,因此,就我们的目的而言,“模型”和“策略”这两个术语可以互换。

加强

我们可以做的一件事是,与其将模型生成的样本视为 SFT 数据并运行多次参数更新,不如在每次参数更新后(或者更实际的更新次数较少,比如少于五次)创建新样本,从而更持续地改进模型,并降低模型在特定输出集上过拟合的可能性。然而,这会使计算负担成倍增加。为了获得单个训练样本,我们已经需要进行多次迭代。因此,在实现这一点之前,我们必须首先解决无法使用所有生成样本的问题。

那么,如果将所有生成的训练样本都计入损失函数,并简单地根据其优劣程度进行加权,效果会怎样呢?上述公式中,当前的 SFT 公式只是对所有样本的损失进行平均,实际上赋予每个被拒绝的样本一个权重。如果我们有一个函数,我们称之为“奖励函数”,它会根据每个样本的优劣程度给出一个分数,结果会怎样呢?这样,我们就可以在训练过程中使用所有生成的样本,并在损失函数中对那些不太好的样本进行适当的加权——甚至加负权。它看起来就像这样:

其中R(text_i)是文本样本text_i的奖励, L(text_i, M)的定义如前所述。这被称为强化算法,由 Williams (1992) 提出。实际上,这种损失函数会导致梯度出现较大方差。为了缓解这种情况,需要从奖励中减去一个基线。基线可以是任意值,但通常使用的是取决于输入到模型中进行下一个标记预测(即s_t )的输入文本的基线。让我们使用V_M(s_t)来表示时间t 的基线。因此,我们无法将奖励函数与等式中的和分开,我们需要展开整个项。它如下所示:

其中text_i是数据集中的第 i个样本文本, a_it表示此文本i的第 t个标记, s_it表示此文本i从 1 到t-1 的标记序列(因此,长度为T的整个文本也可以表示为s_{T+1} )。基线函数V_M(s_t)取决于我们拥有的到t 的文本标记和模型M 。最后, π_M(a_t | s_t)是当标记序列s_t (长度为t-1 个标记)输入模型时,模型M将标记a_t作为下一个标记的概率,如前所述。

回想一下,每个训练样本text_i本质上都是提示和生成的补全的组合(在指令调优的情况下,补全就是响应)。整个提示+响应序列构成一个训练示例。如果一个提示生成多个响应,我们将得到多个文本序列。现在需要注意的一点是,一旦我们有了奖励函数,我们就不再需要对同一个提示进行多次生成。我们可以简单地进行一次生成,改进模型,然后使用改进后的模型进行另一次生成。每个生成的响应都可以用于训练,这使得整个过程比拒绝采样(rejection sample)效率更高。另一点需要注意的是,与 SFT 的情况相同,由于我们希望模型只学习问题的答案而不是问题本身,因此我们从t的值开始对项进行内部求和,使得它对应于字符串text_i中答案的第一个标记,即每个i的t ,使得text_it是问题字符串之后的答案的第一个标记。所有强化学习算法都可以做到这一点,因此我们不会再回顾这一点。

采取行动、获得奖励,并从这些奖励中学习,从而改进未来决策的过程被称为强化学习。强化学习是最简单的强化学习算法之一,它解决了我们关于拒绝采样的前三点。让我们通过理解这些奖励的来源来结束对强化学习的讨论——这与许多强化学习算法都息息相关。

价值函数

将Latex转换为Medium非常累人。关于价值函数、优势函数、TRPO、PPO、GRPO、DPO以及其他所有内容的讨论,可以在这里找到一个格式更佳、可免费获取的PDF文件: https://drive.google.com/file/d/1q8664fOAUTqz1JHPzbvtNgMvVlqwU_77/view ?usp=sharing


《从头开始理解强化学习的模型训练》最初发表在 Medium 上的数据科学集体中,人们通过强调和回应这个故事来继续讨论。

原文: https://medium.com/data-science-collective/understanding-reinforcement-learning-for-model-training-from-scratch-8bffe8d87a07?source=rss-9934e7726dba——2

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Anil Dash
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Big Technology
  • Bits about Money
  • Brandon Skerritt
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • eighty twenty
  • Elad Gil
  • Ellie Huxtable
  • Ethan Dalool
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • HeardThat Blog
  • Henrique Dias
  • Herman Martinus
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Li Haoyi
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Maggie Appleton
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mind Matters
  • Mostly metrics
  • Naval Ravikant
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Rohit Patel
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Steph Ango
  • Stephen Wolfram
  • Steve Blank
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • Wes Kao
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme