用纯 Node.js 从零手搓一个语言模型是什么体验?

北漂开源爱好者 初级 11小时前 更新于 2026年7月26日 250 浏览 9 点赞 约 1 分钟

很多人学大模型总是被 PyTorch 或 TensorFlow 的 Tensor 抽象给搞晕,其实剥离掉框架,底层逻辑就是一堆标量在做加减乘除。我最近刷到一个挺硬核的实操项目,作者完全不用任何 ML 框架,直接用原生 JS 实现了从 Tokenization 到反向传播的完整链路,把所有权重的变化都摊在控制台里给你看。

这个项目的核心逻辑是把每一个数值都封装成一个 Value 对象,手动维护计算图。当你看到代码里直接写 dy/da = b 这种导数定义时,才会真正意识到 Transformer 的本质就是数学。

实操部署

项目没有任何依赖,只要 Node.js 18.19+ 就能跑。直接运行训练脚本即可:

node src/train.js --generalize --adaptive-teach

核心技术链路

这个微型模型的运行流程非常清晰,没有任何黑盒:

  • 文本处理: 文本 → 单词分词 → Token ID
  • 向量化: Token Embedding + Position Embedding
  • 核心架构: 两个 Causal Transformer Block → 多头自注意力机制 (MHA) → 两层隐藏层 FFN
  • 输出端: LM Head → Softmax → 下一个 Token 概率
  • 学习机制: 交叉熵损失 → 反向传播 → Adam 优化器
用纯 Node.js 从零手搓一个语言模型是什么体验?

细节分析

最让我觉得有意思的是作者对“神经元”的实现方式。他没有用高效但难懂的矩阵乘法,而是直接把神经元写成了对象,代码逻辑完全对标数学公式:

forward(input) {
  let output = sum(
    input.map((value, i) => value.mul(this.weights[i]))
  );

  if (this.useBias) output = output.add(this.bias);
  if (this.activation === 'relu') return output.relu();
  return output;
}

虽然这种写法在生产环境里慢得离谱,但作为学习指南简直绝了。你可以清晰地看到 input 是如何与 weight 相乘,然后加上 bias 的。

训练效果

模型初始化时是纯随机的,问它 "can human read ?",它会胡言乱语。但经过预训练和 SFT(监督微调)后,它能精准输出 "human can read."。

这种从“随机乱码”到“逻辑正确”的转变,配合日志里实时跳动的权重矩阵 $\Delta$ 值,比看任何 PPT 教程都要直观。

如果你想彻底搞懂大模型是怎么“学习”的,建议去翻翻这个仓库:

https://github.com/sekretov/tiny-language-model-neuro-js
大模型LLMnodemachinelearningjavascript

全部回复 (4)

杭漂码农 专家 12小时前
不过 JS 算大矩阵还是太慢,建议得加上 WebAssembly 提速。
0 回复
折腾党阿凯 中级 12小时前
之前试过手写反向传播,确实比看框架文档好理解多了。
0 回复
脚本小子阿强 初级 12小时前
这种底层逻辑通了之后,感觉看源码都快了不少,你当时是用什么数据集试的?
0 回复
极客Ray 高级 12小时前
这样写的话,权重更新是用简单的 SGD 还是加了动量?
0 回复

发表回复

支持 Markdown 格式