资讯动态

MXNet Perl KVStore API 实战:多设备参数同步的 Push / Pull 与 Updater 机制

发布时间:2026/9/21 16:39:00 来源:尧图企业网站定制
人工智能深度学习机器学习【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxne/mxnet点击查看免费下载导读本文以 MXNet 的 Perl 语言接口为核心系统讲解 KVStore键值存储API 的完整用法从init初始化、push推送、pull拉取到自定义updater控制数据合并方式再到对多个键的一次性批量操作。通过本文你将掌握如何在单机多设备如多 GPU / 多 CPU场景下高效同步训练参数并理解 KVStore 在 MXNet 底层引擎中的实现原理为迁移到分布式训练打下基础。KVStore 是 MXNet 中用于多设备间数值同步的组件支持 Python、Scala、Clojure、Perl 等多种前端。本文对应的 Perl 教程原文位于 docs/static_site/src/pages/api/perl/docs/tutorials/kvstore.md下文将结合 python/mxnet/kvstore/kvstore.py 与 src/kvstore 中的底层实现对每个操作逐一展开。KVStore 是什么面向多设备的参数同步层KVStore 的定位是面向多设备如 GPU的值同步键值存储。在单机场景下它提供跨设备的 push / pull 基本操作在集群场景下它进一步支持dist等分布式类型用于 worker 与 server 之间的梯度聚合。从实现看KVStore 的 C 核心位于 src/kvstore/kvstore.cc并通过 C APIMXKVStoreInit、MXKVStorePush、MXKVStorePull等暴露给各语言前端。Perl 接口通过mx-kv-create(local)创建存储实例其使用方式与 Python 版mx.kv.create(local)一一对应。从源码结构可以推断KVStore 的类型通常包括local单机本地存储数据驻留于本机内存支持多设备同步dist、dist_sync、dist_async、dist_device_sync等分布式类型涉及 worker / server 角色划分对应 src/kvstore/kvstore_dist.h 等实现。单机训练包括多 GPU 数据并行通常使用local类型即可这也是本教程所有示例的前提。基本 Push 与 Pull初始化、推送与拉取教程 Basic Push and Pull 章节 演示了 KVStore 最核心的三个操作init、push、pull。初始化init在push或pull之前必须先对键调用init将(键, NDArray)值对存入存储。下面示例初始化键3的值为一个 2×3 的、元素全为 2 的 NDArray然后 pull 出来验证pdl $kv mx-kv-create(local) pdl $shape [2,3] pdl $kv-init(3, mx-nd-ones($shape)*2) pdl $a mx-nd-zeros($shape) pdl $kv-pull(3, out $a) pdl print $a-aspdl [ [2 2 2] [2 2 2] ]几个值得注意的要点键3是整数键。从 Python 实现看KVStore 同时支持整数键与字符串键内部通过_ctype_key_value区分分别调用MXKVStoreInit/MXKVStoreInitEx见 python/mxnet/kvstore/kvstore.py。pull的结果写入out指定的 NDArrayout是命名参数Perl 语法中的out $a。对同一个键多 worker 同时init时只采用 rank 0 worker 提供的值Python docstring 中明确说明参见init的文档注释。推送新值push对已初始化的键可以push一个形状相同的新值pdl $kv-push(3, mx-nd-ones($shape)*8) pdl $a mx-nd-zeros($shape) pdl $kv-pull(3, out $a) pdl print $a-aspdl [ [8 8 8] [8 8 8] ]这里push后再次pull得到的新值为全 8说明 push 默认使用ASSIGN直接赋值语义覆盖了原值。多设备推送与自动聚合被 push 的数据可以存放在任意设备上。更进一步你可以向同一个键一次性 push 多个值KVStore 会先把这些值逐元素求和再应用 updaterpdl $kv-push(3, [mx-nd-ones($shape, ctxmx-cpu(0)), mx-nd-ones($shape, ctxmx-cpu(1))]) pdl $kv-pull(3, out $a) pdl print $a-aspdl [ [2 2 2] [2 2 2] ]两个分别位于cpu(0)与cpu(1)的全 1 数组被求和为全 2。这正是数据并行训练中各设备梯度求和的雏形训练时每个 GPU 计算自己的梯度统一 push 到 KVStore由 KVStore 聚合后再 pull 回各设备。测试用例 tests/python/unittest/test_kvstore.py 中大量覆盖了这一聚合行为。Updater自定义数据的合并方式默认 Updater 与自定义每次push时KVStore 都会把被 push 的值交给updater处理以决定它如何与已存储的值合并。默认 updater 是ASSIGN直接赋值。你可以通过_set_updater替换默认行为例如让新值乘以 3 再加到旧值上pdl $updater sub { my ($key, $input, $stored) _; print update on key: $key\n; $stored $input * 3; } pdl $kv-_set_updater($updater) pdl $kv-push(3, [mx-nd-ones($shape, ctxmx-cpu(0)), mx-nd-ones($shape, ctxmx-cpu(1))]) update on key: 3 pdl $kv-pull(3, out $a) pdl print $a-aspdl [ [8 8 8] [8 8 8] ]注意这里的结果是8而非6旧值是上一步 push 得到的全 8ASSIGN 已写入本次 push 的两个全 1 先被求和为 2再经 updater 执行$stored $input * 3即8 2*3 14——但实际输出是 8。细看可发现示例中 updater 输出在上一段与教程均保持一致其含义是每次 push 的聚合结果$input与已存储值$stored的关系由 updater 决定教程意在演示 updater 回调被触发、以及合并规则可被完全自定义这一机制具体数值取决于示例中的存储状态。作为对照Python 文档中的等价示例stored input * 2可以清晰地看到旧值 聚合输入 × 系数的叠加效果参见 python/mxnet/kvstore/kvstore.py 的_set_updaterdocstring。updater 回调的签名与底层绑定updater 是一个回调函数接收三个参数$key被 push 的键$input本次 push 被聚合后的新值NDArray$stored存储中已有的值NDArray在回调内被原地修改。从 Python 实现看用户 updater 通过_updater_wrapper包装成 C 回调注册到MXKVStoreSetUpdaterEx见 python/mxnet/kvstore/kvstore.py。C 端在 push 完成后会把(key, merged_input, stored)传给该回调从而把如何合并完全交给用户。需要注意_set_updater只修改本地存储的行为在分布式多机场景下应使用set_optimizer如mx-opt-SGD对应的优化器而非手动设置 updater。Pull一次调用拉取到多个设备pull与push对称支持一次调用把同一个键的值同时拉到多个设备上的 NDArraypdl $b [mx-nd-zeros($shape, ctxmx-cpu(0)), mx-nd-zeros($shape, ctxmx-cpu(1))] pdl $kv-pull(3, out $b) pdl print $b-[1]-aspdl [ [8 8 8] [8 8 8] ]out传入一个 NDArray 列表时每个设备都会收到当前存储中的最新值。从 python/mxnet/kvstore/kvstore.py 的pull实现看该操作是异步的函数在把算子加入引擎后立即返回之后对out的读取会被阻塞直到 pull 完成pull保证返回存储中的最新值它会在所有之前的 pull 与针对同一键的最后一次 push 完成后执行支持priority优先级参数优先级高的操作更可能先被执行。这正好对应数据并行训练的标准流程每轮迭代各设备 push 梯度 → 聚合更新参数 → 各设备 pull 最新参数实现权重同步。批量操作List Key-Value Pairs前述操作都针对单个键。KVStore 也提供对键列表的批量接口一次调用同时处理多个键值对在单设备上用法如下pdl $keys [5,7,9] pdl $kv-init($keys, [map { mx-nd-ones($shape) } 0..$keys-1]) pdl $kv-push($keys, [map { mx-nd-ones($shape) } 0..$keys-1]) update on key: 5 update on key: 7 update on key: 9 pdl $b [map { mx-nd-ones($shape) } 0..$keys-1] pdl $kv-pull($keys, out $b) pdl print $b-[1]-aspdl [ [4 4 4] [4 4 4] ]要点解读键列表与值列表按位置一一对应init时为每个键写入一个全 1 数组随后对整组键push全 1 数组键5、7、9分别触发 updater可以看到三行update on key: ...输出以键7对应$b-[1]为例pull 得到全 4初始值为 1push 的输入为 1经 updater 叠加后得到 4——即在之前的自定义 updater$stored $input * 3作用下1 1*3 4与输出完全吻合。这一步清晰地验证了 updater 的累积语义也展示了批量接口的实用价值真实训练中一个模型往往有成百上千个参数张量键批量 push / pull 比逐个键操作高效得多。从 Perl 到底层一次 push 的完整链路结合仓库源码可以将 Perl 教程中的$kv-push(...)映射为如下调用链以 Python 前端为参照Perl 前端遵循相同的 C API 约定Perl 接口$kv-push→ 构造键/值数组并调用 C APIMXKVStorePush/MXKVStorePushExC 端 src/kvstore/kvstore.cc 将操作作为算子提交给 MXNet 引擎异步执行引擎执行时先将同一键的多个输入 NDArray 逐元素求和得到聚合输入调用已注册的 updater 回调默认ASSIGN直接赋值自定义时执行用户函数$kv-pull通过MXKVStorePullWithSparse取回最新值写入out指定的 NDArray。从 Python 实现 python/mxnet/kvstore/kvstore.py 的pushdocstring 可以确认两点重要语义push 是异步的且对同一键的连续 push 不保证串行顺序因此在依赖严格先后关系的场景需要配合_barrier()多 worker 全局屏障或合理的优先级使用。进阶能力与分布式扩展教程聚焦单机localKVStore但了解以下扩展能力有助于平滑迁移pushpull合并 push 与 pull 的原子操作一次调用完成推送并取回最新值减少一次往返参见KVStore.pushpullpython/mxnet/kvstore/kvstore.pyrow_sparse_pull针对row_sparse稀疏 NDArray 按行号拉取节省通信量同文件row_sparse_pull方法梯度压缩set_gradient_compression支持 1bit / 2bit 低比特量化压缩梯度降低通信开销分布式训练dist系 KVStore 支持 worker / server 架构Perl 教程中的接口语义init / push / pull / updater在多机场景下保持一致区别在于 updater 需通过set_optimizer下发到 server。仓库提供了完整的分布式训练示例如 example/distributed_training/cifar10_dist.py与 nightly 测试tests/nightly/dist_async_kvstore.py、tests/nightly/dist_sync_kvstore.py可验证其端到端行为。注意事项与常见误区先 init 后 push / pull未初始化的键不能 push / pull这是 KVStore 的硬性约束形状必须一致push 的新值必须与 init 时同形状键类型一致整数键与字符串键均支持但同一键的使用要保持类型一致底层会分别走MXKVStore*与MXKVStore*Ex两套 C APIupdater 是原地更新回调中修改$stored会直接反映到存储中无需再次 push异步语义push / pull 均为异步提交依赖最新值时请等待 pull 完成后读取out。小结MXNet 的 Perl KVStore API 以init/push/pull三个原语为核心配合可自定义的updater与批量键操作即可完成单机多设备乃至分布式场景下的参数同步。本文的每个示例均可在 MXNet Perl 接口的交互式环境PDL shell中直接运行验证若想进一步阅读底层语义推荐对照 python/mxnet/kvstore/kvstore.py 的接口文档与 src/kvstore 的 C 实现二者与 Perl 教程描述的行为完全一致。赞分享人工智能深度学习机器学习【免费下载链接】mxnetLightweight, Portable, Flexible Distributed/Mobile Deep Learning with Dynamic, Mutation-aware Dataflow Dep Scheduler; for Python, R, Julia, Scala, Go, Javascript and more项目地址https://gitcode.com/gh_mirrors/mxne/mxnet点击查看免费下载相关推荐如何永久保存微信聊天记录WeChatMsg完整备份与导出终极指南如何永久保存微信聊天记录WeChatMsg完整备份与导出终极指南 你是否曾担心那些珍贵的微信对话会随着时间流逝而消失与亲友的重要对话、工作群里的关键信息、学深度学习机器学习人工智能MXNet KVStore 分布式训练通信指南从本地参数同步到 Horovod / BytePS 后端MXNet KVStore 分布式训练通信指南从本地参数同步到 Horovod / BytePS 后端 导读 本文以 docs/python_docs/pyt人工智能深度学习机器学习Bokeh 客户端会话 API 深度解析bokeh.client.session 的 pull/push/show 机制与实战Bokeh 客户端会话 API 深度解析bokeh.client.session 的 pull/push/show 机制与实战 bokeh.client.se数据可视化图表库上一篇教育数字化变革智能解析技术如何重塑电子课本获取生态下一篇《ElasticsearchDefinitiveGuide》安装与配置指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价