news 2026/10/19 8:59:10

In-context Learning 代码库深度解析:用线性模型探究 Transformer 的隐式学习算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
In-context Learning 代码库深度解析:用线性模型探究 Transformer 的隐式学习算法
  • 人工智能
  • 深度学习
  • NLP
  • 计算机视觉
  • 强化学习

【免费下载链接】google-research

Google Research

项目地址:https://gitcode.com/gh_mirrors/go/google-research
点击查看免费下载

本指南以google-research仓库中 incontext/README.md 所指向的预印本研究《What Learning Algorithm is In-context Learning? Investigations with Linear Models》为骨架,系统拆解 incontext/ 代码库的全部实现:数据生成、Transformer 训练、对比算法、探针模型与可视化工具。读者读完本文后,将掌握这套实验框架的完整调用链、全部命令行参数含义,并能复现"上下文内学习(In-context Learning,ICL)究竟等价于哪种经典学习算法"这一核心实验。

一、研究背景与代码库定位

大语言模型能够在提示中通过少量示例(few-shot exemplars)完成新任务而不更新权重,这一现象被称为 In-context Learning。一个核心科学问题是:Transformer 在上下文内执行的"隐式学习算法"到底是什么?

incontext/README.md 明确指出,本仓库对应预印本论文:

What Learning Algorithm is In-context Learning? Investigations with Linear ModelsEkin Akyürek, Jacob Andreas, Dale Schuurmans, Tengyu Ma, Denny Zhou

该研究采用"用线性模型做实验"的策略:把 ICL 问题简化为线性回归的上下文内学习——即给定若干(x, y)示例后,让 Transformer 预测新输入x对应的y。由于线性回归存在解析解(最小二乘、岭回归等),研究者可以把 Transformer 在上下文内隐式学习的"行为权重"(behavioral weight)与经典算法逐一对照,从而判定其内部实现的算法类型。

代码库本身是一个可运行的实验框架,由以下模块构成(目录结构见 incontext/):

文件职责
incontext/incontext/sampler_lib.py线性回归数据的随机采样与分布字符串解析
incontext/incontext/transformer_lib_flax.pyFlax Transformer 主干与学习率调度器
incontext/incontext/predictor_flax.py因果语言模型(CausalLM)预测头与损失计算
incontext/incontext/model_trainer.py主模型训练、评估与可视化入口
incontext/incontext/main.py实验入口:参数解析、训练调度、探针可选训练
incontext/incontext/algos.py经典回归算法集合与在线回归评测
incontext/incontext/probe_flax.py / probe_trainer.py从隐状态解码权重的探针模型
incontext/incontext/plotting.py经验分布、隐式权重路径等可视化
incontext/incontext/linear_model.py / train_linear_lib.py单层线性模型的 SGD/GD 基准训练
incontext/incontext/utils.py随机种子、Flag 转配置等公共工具
incontext/run.sh / requirements.txt / setup.py环境搭建与打包

依赖以 JAX 生态为主:requirements.txt 声明了flax、jax、matplotlib、tensorflow(用于gfile文件读写)、numpy、absl-py、optax;此外 algos.py 还直接使用了sklearn的linear_model、neighbors、metrics模块。

二、数据生成:Sampler 与分布字符串语法

2.1 分布字符串的解析规则

训练与评估的数据分布完全由字符串控制,解析逻辑在 sampler_lib.py 的str_to_distribution_fn中:

  • 单分布格式为类型*alpha+beta:类型仅支持uniform(np.random.rand)与normal(np.random.randn),采样结果乘以alpha并加上beta。例如默认值"normal*1.0+0.0"即标准正态分布,"normal*2.5+0"表示标准差放大到 2.5,"normal*1+2.5"表示均值偏移到 2.5。
  • 混合分布用逗号连接多个单分布,例如"normal*1+0,uniform*1+0"。此时每个子分布各采样一份 batch,再按 batch 维度随机挑选合并,等效于均匀混合采样。
  • 未知类型会抛出ValueError("Unknown distribution type.")。

2.2 Sampler 的序列构造

Sampler类(sampler_lib.py)负责生成一条完整的上下文序列,核心参数包括:

  • length:示例(exemplar)个数;
  • dim:x向量的维度;
  • hidden_size:序列向量的维度(填充后的宽度);
  • x_distribution_fn/w_distribution_fn:x与回归系数w的采样函数;
  • noise_std:大于 0 时给y添加高斯噪声,默认 0.0。

sample()方法(sampler_lib.py)的核心逻辑是:为每个示例依次采样x与系数w,通过np.einsum("bi,bi->b", coefficients, x)计算y,然后将x_vec([0, x]前置零位)与y_vec([y, 0...0]后置dim个零填充)交替拼接成一条长度为length * 2的序列,返回(out, coefficients, xs, ys)四元组。这种"x 与 y 交替、零填充对齐维度"的编码方式,与后续CausalLM中按偶数位抽取y的损失设计一一对应(详见第三节)。

2.3 对训练与评估的影响

noise_std直接控制任务难度:在 model_trainer.py 中,主训练用的Sampler以x_distribution_str、w_distribution_str、noise_std构造;而在评估阶段 model_trainer.py 会额外以eval_noise_std = x_dim / 20生成带噪声的测试分布,用于考察模型对标签噪声的鲁棒性。此外 test_empirical_statistics 中采样num_exemplars - 1个示例并注释说明"否则用于最后一个示例的位置编码将是未训练参数"——这是序列长度与位置编码最大长度(max_len=(num_exemplars+1)*2)之间必须留出余量的直接证据。

三、Transformer 实现:CausalLM 与自注意力补丁

3.1 CausalLM:按偶数位取 y 的自回归损失

incontext/incontext/predictor_flax.py 定义了CausalLM模块。前向流程为:

  1. 取seq_from = inputs[:, :-1, :](预测下一位置);
  2. 用nn.attention.make_causal_mask构造因果掩码;
  3. 送入 transformer_lib_flax.py 的Transformer,可返回各层注意力权重;
  4. 经nn.Dense投影(默认输出维度 1,即只预测 y;开启loss_on_x_steps时预测完整向量);
  5. extract_y(predictor_flax.py)按jnp.arange(offset, seq.shape[1], 2)取出偶数位置,即只保留 y 步的预测;
  6. 损失为预测 y 与目标 y 的平方误差和((y_pred - y_target)**2).sum(axis=-1)),可选的return_attention=True会把各层注意力权重一并返回,供可视化使用。

loss_on_x_steps标志定义在 predictor_flax.py,默认False,表示只对 y 步计算损失。

3.2 Transformer 主干与可配置项

transformer_lib_flax.py 的TransformerConfig定义了全部结构超参数,而对应的命令行 Flag 定义在文件开头(L45-L73):

Flag默认值含义
n_layers12编码器层数
n_heads8注意力头数(要求hidden_size % n_heads == 0)
hidden_size512模型宽度
norm_firstTruePre-LN:先 LayerNorm 再注意力/MLP
final_layer_normFalse是否在输出前追加最后一层 LayerNorm
disable_layer_normsFalse完全禁用 LayerNorm(消融用)
inner_dimNoneMLP 中间维度,None 时取hidden_size * 4
kernel_init/bias_inituniform_scaling注意力/MLP 参数初始化器
linear_w_init/linear_bias_inituniform_scaling投影层初始化器
posemb_inituniform_scaling位置嵌入初始化器
activation_fngelu激活函数(可选 gelu/relu/tanh/softplus/sofu)

Transformer的组成(L355-L408):先经nn.Dense投影到hidden_size,再加可学习位置嵌入(PositionEmbeddings,L189-L221,按max_len截取),然后堆叠num_layers个Encoder1DBlock(L267-L352),每个块为"自注意力 + 残差 + MLP + 残差"结构。初始化器支持字符串解析(nn_init_parser,L127-L140):uniform_scaling、ones、zeros、normal(std)。

3.3 自注意力补丁:返回注意力权重

incontext/flax/self_attention_patch.py 是从flax.linen.attention复制并改造的版本:在 dot_product_attention 与MultiHeadDotProductAttention中增加了return_attention分支,使注意力权重可以被返回并序列化。Encoder1DBlock调用的是补丁版SelfAttention(transformer_lib_flax.py),其qkv_features=hidden_size // num_heads。这一改动直接服务于 model_trainer.py 中导出attention_stats.pkl的分析需求——研究者借此观察注意力在示例之间如何分配权重。

四、训练管线与命令行参数全解

4.1 实验入口 main.py

incontext/incontext/main.py 是标准实验入口,流程为:解析 flags →utils.flags_to_args()生成ConfigDict→ 创建实验目录并写config.json→utils.set_seed→ 初始化模型 → 训练主模型 → 保存metrics.pickle与 checkpoint → 可选训练探针。其自有 Flag:

Flag默认值含义
seed0随机种子(同时作用于 Python、numpy 与 JAX)
batch_size64每步采样的序列条数
x_dim20输入维度(也是系数维度)
num_exemplars40每条序列的示例个数
exp_folderexp实验输出目录
debugFalse调试预测与后验分布
train_probeFalse主模型训练完成后是否追加训练探针

主模型训练与评估 Flag 定义在 model_trainer.py:

Flag默认值含义
n_epochs5001训练轮数
n_iter_per_epoch100每轮迭代次数
learning_rate1e-4基础学习率
weight_decay0AdamW 权重衰减
lr_scheduler_typecosinecosine / warmup / 常数
adam_b10.9Adam 一阶动量
adam_b20.98Adam 二阶动量
adam_eps1e-9Adam 数值稳定项
x_distribution_strnormal*1.0+0.0训练时 x 的分布
w_distribution_strnormal*1.0+0.0训练时 w 的分布
noise_std0.0训练标签噪声标准差

4.2 训练步骤与多设备并行

train_step(model_trainer.py)实现单步更新:jax.value_and_grad求梯度,jax.lax.pmean(grads, "batch")做跨设备梯度平均,state.apply_gradients更新参数,损失经pmean汇总、y_errors经psum求和。模型通过jax.pmap并行化(L317-L320),数据用common_utils.shard分片到各设备,dropout 随机数按设备拆分(L418-L420)。

优化器为optax.adamw(L301-L307),学习率调度有三种选择,由lr_scheduler_type控制(L284-L299):

  • cosine:create_learning_rate_scheduler(transformer_lib_flax.py),warmup 步数为(n_epochs // 5) * n_iter_per_epoch,随后按半余弦周期衰减;
  • warmup:create_learning_rate_scheduler_v2(L448-L516),因子串"constant * linear_warmup";
  • 其他:恒为learning_rate的常数调度。

train主循环(model_trainer.py)每eval_every_n_epochs(默认 1000)触发一次eval_model,并把每轮指标堆叠保存;checkpoint 经flax.training.checkpoints.save_checkpoint写入exp_folder/ckpt/(L226-L248)。

4.3 跨分布评估

eval_model(model_trainer.py)在固定测试分布集合上分别扰动w 分布与x 分布进行评估。默认测试集为("normal*1+0", "normal*2.5+0", "normal*1+2.5");当训练分布本身是混合分布(x_distribution_str含逗号)时,还会追加"normal*1+-2.5"与"normal*1+5.0"(L431-L444)。每轮评估输出到exp_folder/plots/distribution/w_{str}/与x_{str}/子目录,其中*被替换为x以兼容文件系统;x 扰动下还会生成noise_{x_dim/20}/子目录对应带噪测试。

五、对比算法集合:ICL 的"候选学习算法"

5.1 统一接口与评分

incontext/incontext/algos.py 定义了RegressionAlgorithm抽象基类(L50-L120),统一接口为fit(x, y)、predict(x)、get_parameters()、iterate(x, y)、is_iterative()、reset(),并提供scores()计算 R2 与 MSE。实现包括:

  • LeastSquareAlgorithm(L123-L148):sklearn.linear_model.LinearRegression,即标准最小二乘;
  • FakeLeastSquareAlgorithm(L151-L180):直接使用先验精度矩阵计算weight = (precision @ x.T @ y) / n的"伪最小二乘"(对应文中Lstsq-Constant-Sigma);
  • RidgeRegressionAlgorithm(L183-L214):sklearn.linear_model.Ridge,alpha默认 0.01;
  • KNNAlgorithm(L217-L243):sklearn.neighbors.KNeighborsRegressor,支持 uniform / distance 加权;
  • SGD(L246-L306):自实现随机梯度下降,window=1表示在线(只看当前样本),window=-1表示全量梯度,梯度裁剪到[-20, 20],支持weight_decay。

5.2 在线回归评测

核心评测函数online_regression(algos.py)模拟"上下文内学习"过程:对每条序列,遍历第 1 到最后一个示例,迭代式算法(is_iterative())用当前样本iterate,非迭代算法用fit(x[:i])重拟合,随后预测下一个x_i并记录预测与参数。online_regression_with_batch(L332-L349)批量执行并返回逐示例的 MSE 曲线。

值得一提的细节:algos.py的if __name__ == "__main__"分支(L352-L503)是一个可直接运行的算法对比实验——在x_dim=10, hidden_size=128, num_exemplars=64下对 16 种算法变体(不同学习率、窗口、权重衰减、Ridge alpha、KNN 加权)在三种 w/x 分布下绘制 MSE 曲线,保存为algos_w_*.jpeg/algos_x_*.jpeg。这是"先有候选算法、再与 Transformer 行为对齐"方法论的直接体现。

六、探针模型:从隐状态解码真实权重

除了行为层面的对比,代码库还提供了权重层面的探针:直接训练一个线性解码器,从 Transformer 各层最后一个 token 的隐状态恢复回归系数。

incontext/incontext/probe_flax.py 的ProbeModel对每一层独立使用一个nn.Dense(config.x_dim),输入该层最后一个位置的 hidden state,输出与真实系数coefficients对比求平方误差,最终返回形状为 batch 的逐层误差堆叠。ProbeConfig(L42-L51)包含hidden_size、num_layers、x_dim、max_len等字段。

incontext/incontext/probe_trainer.py 负责探针训练:

  • 用冻结的主模型(state.params)前向得到seq_hiddens(L115-L117),转置为(layer, batch, len, hidden)后分片;
  • 训练循环与主模型一致,采用optax.adamw与 cosine 调度(L189-L212);
  • 新增 Flag:probe_learning_rate(默认 0.001)、probe_epochs(默认 20)、probe_iters(默认 100)、probe_lr_scheduler_type(默认 cosine)。

探针的意义在于:如果某层隐状态能被线性映射出精确的回归系数,就说明该层内部"编码"了最小二乘等算法对应的解,为"Transformer 隐式执行了某类学习算法"提供内部证据。

七、可视化与实证分析工具

incontext/incontext/plotting.py 提供三类核心可视化,全部由 model_trainer.py 的test_empirical_statistics触发,输出在exp_folder/plots/下:

  1. 行为权重的经验拟合:plot_empirical_distribution(L75-L322)用模型对一组随机x的预测y_pred反拟合一个带截距的最小二乘模型(algo_fn(fit_intercept=True)),得到"行为权重"w_empirical与 R2;随后绘制:

    • 3D 经验平面(红色)与真实平面(蓝色)对比(plot_planes_3d,L62-L72);
    • 逐示例的预测误差曲线(_errors.jpeg)、与最小二乘/岭回归/SGD 等算法的误差对比(plot_an_algorithm调用online_regression_with_batch);
    • 各算法与 Transformer 预测的发散度曲线(_divergence.jpeg);
    • 可选的预测序列保存(_predictions.pkl)。
  2. 隐式权重路径:plot_implicit_w(L325-L382)在每个示例前缀长度上重复"预测→反拟合"过程,绘制w_empirical在权重空间中的轨迹(_w.jpeg)、各前缀 R2(_r2.jpeg),以及与真实最小二乘权重差异||Wlsq2-Wimp||^2随示例数变化的曲线(_wdiff.jpeg)——这是判定"ICL 是否收敛到最小二乘"最直观的证据图。

  3. 基向量可视化:plot_basis_image(L385-L428)逐个维度构造只有该维度非零的x,比较模型预测(红点)与真实y(蓝点)的散点图,检查模型是否在每个坐标方向上对齐。

此外,average_stats.jpeg、average_stats.pkl与attention_stats.pkl汇总了平均预测误差与各层注意力权重,供后续离线分析。

八、线性基准:单层模型的 SGD/GD 对照

为回答"ICL 等价于什么算法",incontext/incontext/linear_model.py 与 incontext/incontext/train_linear_lib.py 还提供了一个显式线性层 + SGD/GD的对照组:LinearModel(linear_model.py)只是一个无偏置的nn.Dense(1),LinearConfig.alpha控制 L2 正则强度。

train_linear_lib.py 的run_exp(L98-L163)在每条序列上运行optax.sgd,其中gd=True时用全量历史样本计算梯度(梯度下降),gd=False时只用当前样本(真正的 SGD),并逐示例记录下一示例的预测损失。main(L166-L202)默认在x_dim=10、num_exemplars=32、w 分布normal*1+5.0下采样并平均多条序列的损失,输出losses.png。该实验用于刻画"显式 SGD 在同样任务上的学习曲线",作为与 Transformer 隐式行为对照的基准。

九、环境搭建与运行指南

9.1 依赖安装

仓库提供两种方式:

  • 一键脚本:run.sh 执行virtualenv -p python3 .创建本地虚拟环境、source ./bin/activate激活、pip install -r requirements.txt安装依赖,随后运行python -m incontext.utils验证模块可导入。注意该脚本基于 Bash 与virtualenv,需要预先安装对应工具。
  • 手动安装:直接pip install -r requirements.txt,或执行pip install .(setup.py 以setuptools将包注册为incontext)。

值得提醒:requirements.txt未显式列出scikit-learn,但 algos.py 与 least_square.py 均直接import sklearn,因此运行对比算法实验前需自行补装scikit-learn。模型训练需要 JAX 可用的后端(CPU/GPU/TPU 均可,多设备时自动启用pmap并行)。

9.2 复现 Transformer 主实验

以 main.py 的默认参数(x_dim=20、num_exemplars=40、batch_size=64、n_epochs=5001、hidden_size=512、n_layers=12、n_heads=8)为例:

# 训练 + 评估(含绘图与 checkpoint) python -m incontext.main \ --seed=0 \ --x_dim=20 \ --num_exemplars=40 \ --batch_size=64 \ --n_epochs=5001 \ --exp_folder=exp # 附加探针训练 python -m incontext.main --train_probe=True --exp_folder=exp # 修改训练分布(如增大 w 方差) python -m incontext.main --w_distribution_str="normal*2.5+0" --exp_folder=exp_w2p5

运行产物集中在exp_folder:config.json(参数快照)、metrics.pickle(逐步指标)、ckpt/(可恢复的 checkpoint)、plots/distribution/(全部可视化与统计数据)。

9.3 运行算法对比与线性基准

# 经典算法集合的 MSE 曲线(直接执行 algos.py 的 main 分支) python -m incontext.algos # 单层线性模型 SGD/GD 基准 python -m incontext.train_linear_lib --seed=0 --x_dim=10 --num_exemplars=32 --batch_size=32 # 最小二乘变体对比示例(least_square.py 的 main 分支,含伪最小二乘) python -m incontext.least_square

十、总结:这套框架回答了什么问题

纵观全库,incontext/ 的贡献是一套**"算法归因"实验方法论**:在可控的线性回归 ICL 任务上,同时实现(a)数据分布参数化采样(第二节)、(b)可配置的因果 Transformer 训练与跨分布评估(第三、四节)、(c)一组候选经典算法与在线回归评测(第五节)、(d)权重层面的探针解码(第六节)、以及(e)行为权重路径与误差发散可视化(第七节)。通过对比 Transformer 的行为权重、隐式权重轨迹与最小二乘/SGD 等算法的对应关系,即可实证检验论文提出的核心主张——ICL 内部执行的隐式学习算法究竟与哪一类经典算法一致。

需要说明的是:本仓库提供的是实验代码与工具链,论文的完整实验结论与数据需以预印本正文为准;本文所有实现细节均来自 incontext/README.md 及上述源码文件,可直接对照查阅。

  • 人工智能
  • 深度学习
  • NLP
  • 计算机视觉
  • 强化学习

【免费下载链接】google-research

Google Research

项目地址:https://gitcode.com/gh_mirrors/go/google-research
点击查看免费下载
上一篇:CANN/asc-devkit浮点转整型函数
下一篇:Tutu.ru PHP 后端开发测试题全解析:从基础算法到购物车折扣、分布式 Cron 与 Telegram Bot 的完整题解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 10:38:19

武警执勤单视频三维重构在重点目标立体安防中的应用

摘要武警执勤重点目标涵盖党政要害、重要场馆、交通枢纽、监所营地、核心设施等关键安防点位,承担固定守卫、区域警戒、动态巡防、应急处突等核心执勤任务,具有安防等级高、警戒区域立体多层、人流车流密集、突发态势多样、隐蔽风险突出、全天候值守要求…

作者头像 李华
网站建设 2026/10/15 10:50:24

Redis 8.4网络IO深度拆解:从事件循环到IO线程池的架构演进

1. 为什么Redis 8.4的网络IO值得一次深度拆解做后端这么久,Redis 一直是我压测报告里最无聊也最可靠的那个角色。别的组件动不动就 CPU 飙红、连接打满,Redis 大多数时候就是一条平稳的直线。但这份“无聊”背后,恰恰是它网络 IO 架构在兜底。…

作者头像 李华
网站建设 2026/10/14 13:59:47

revali鸿蒙适配实战:Dart全栈服务嵌入鸿蒙设备全指南

最近我手头有个 IoT 场景的项目,前端选了 Flutter 跨端做界面,后端接口又不想再起一套 Node 或 Java 服务,就想着能不能直接用 Dart 把全栈都干了。翻了一圈生态,shelf 太裸、aqueduct 停更多年、dart_frog 又偏向轻量路由&#x…

作者头像 李华
网站建设 2026/10/16 6:36:27

植物大战僵尸杂交版v3.15攻略:从下载安装到高阶阵容搭配

1. 内容整体设计与思路拆解1.1 杂交版到底是什么,为什么能火成这样植物大战僵尸杂交版,说白了就是一群脑洞极大的玩家,在原版《植物大战僵尸》的基础上做的大规模二创魔改。它不是简单调几个数值、换个皮肤,而是把两种甚至三种植物…

作者头像 李华