从 PyTorch 迁移到 Apache MXNet Gluon:API 对照、MNIST 实战与自动求导原理
人工智能深度学习机器学习【免费下载链接】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点击查看免费下载Apache MXNet 的 Gluon 接口提供与 PyTorch 几乎一致的命令式imperative编程体验同时支持通过hybridize()将网络转换为符号图以获得额外性能收益。本文以官方教程 PyTorch vs Apache MXNet 为主体完整对比两个框架在安装、数据操作、模型训练全流程中的差异结合仓库源码剖析autograd、Trainer、HybridBlock等核心机制的底层实现并附上全面的 API 对照速查表帮助 PyTorch 开发者快速完成迁移。为什么关注 PyTorch 与 MXNet 的迁移PyTorch 因其直观的 API 与彻底的命令式imperative编程风格广受欢迎。Apache MXNet 的 Gluon API 同样提供命令式的简洁与灵活在此之上还能将网络混合hybridize为符号图以利用符号计算图的性能优化能力。原教程引用了 2019 年 4 月 NVIDIA 的性能基准在训练 ResNet-50 时 Apache MXNet 达到 10,925 images/sPyTorch 为 6,175 images/s即 MXNet 领先约 77%数据来自原文档引用的 NVIDIA 官方基准请注意该数据反映的是彼时版本与硬件的对比实际表现应以当前版本实测为准。对 PyTorch 用户而言两框架的学习曲线非常平缓——核心差异集中在术语Tensor vs NDArray与梯度累积行为PyTorch 累积、MXNet 覆盖两点上其余代码几乎可以一一对应搬移。安装方式对比PyTorch 默认使用 conda 安装MXNet 则推荐 pip# PyTorchconda 安装 CPU 版本 # !conda install pytorch-cpu -c pytorch, torchvision # MXNetpip 安装 CPU 版本 # !pip install mxnetMXNet 安装 GPU 版本时需要显式指定 CUDA 版本例如安装 CUDA 10.2 支持# !pip install mxnet-cu102仓库中对应不同 CUDA 版本的构建配置位于 config/distribution如linux_cu101.cmake、linux_cu102.cmake读者可根据自身 CUDA 环境选择匹配的 pip 包。数据操作Tensor 与 NDArray两个框架都以多维矩阵作为数据载体。PyTorch 沿用 Torch 的命名习惯称为 tensorMXNet 遵循 NumPy 惯例称为 NDArray。下面的例子创建一个每个元素均为 1 的二维矩阵对每个元素加 1 后打印结果# PyTorch import torch x torch.ones(5, 3) y x 1 y# MXNet from mxnet import np x np.ones((5, 3)) y x 1 y两者唯一的明显差异是包名以及 MXNet 的形状shape参数需要像 NumPy 一样以括号包裹的元组传入np.ones((5, 3))而 PyTorch 直接传多个整数torch.ones(5, 3)。两个框架都提供了丰富的张量/NDArray 创建与操作函数。从源码结构看MXNet 的 NumPy 兼容接口由python/mxnet/numpy与 src/operator/numpy 提供mxnet.np模块目标是让 NumPy 代码几乎零成本迁移到 GPU 上运行。MNIST 实战MLP 训练的四个步骤下面以 MNIST 手写数字识别、多层感知机MLP为例将训练流程拆分为四个步骤进行逐段对比。第 1 步读取数据# PyTorch from torchvision import datasets, transforms trans transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.13,), (0.31,))]) pt_train_data torch.utils.data.DataLoader(datasets.MNIST( root., trainTrue, downloadTrue, transformtrans), batch_size128, shuffleTrue, num_workers4)# MXNet from mxnet import gluon from mxnet.gluon.data.vision import datasets, transforms trans transforms.Compose([transforms.ToTensor(), transforms.Normalize(0.13, 0.31)]) mx_train_data gluon.data.DataLoader( datasets.MNIST(trainTrue).transform_first(trans), batch_size128, shuffleTrue, num_workers4)两个框架都能自动下载 MNIST 数据集并指定仅取训练集。核心差异在于 MXNet 使用 transform_first 方法表示变换只作用于数据批的第一个元素MNIST 图片而不作用于第二个元素标签。从源码看transform_first定义于 python/mxnet/gluon/data/dataset.py其实现为self.transform(_TransformFirstClosure(fn), lazy)即内部复用了transform机制并包装一个只作用于首个元素的闭包lazyTrue默认表示按需逐个变换样本如果变换函数是随机的如数据增强必须保持 lazy 为 True否则所有 epoch 会得到相同结果。这正是 MNIST 这类图片在第一个元素、标签在第二个元素的数据集的标准用法。第 2 步创建模型下面定义一个单隐藏层 MLP输出层 10 个单元# PyTorch import torch.nn as pt_nn pt_net pt_nn.Sequential( pt_nn.Linear(28 * 28, 256), pt_nn.ReLU(), pt_nn.Linear(256, 10))# MXNet import mxnet.gluon.nn as mx_nn mx_net mx_nn.Sequential() mx_net.add(mx_nn.Dense(256, activationrelu), mx_nn.Dense(10)) mx_net.initialize()两个框架都用Sequential容器逐层堆叠网络但 MXNet 与 PyTorch 有三点差异输入尺寸可自动推断PyTorch 的Linear必须显式给出输入大小如Linear(28*28, 256)MXNet 允许省略输入维度在第一次前向传播后自动推断为网络结构设计提供了额外灵活性。激活函数直接内嵌MXNet 可以在全连接层、卷积层内直接通过activationrelu指定激活函数无需单独添加 ReLU 层。显式初始化模型结构定义完成后MXNet 需要显式调用initialize()。Sequential让层按顺序依次执行若要自定义执行流程PyTorch 可继承nn.Module并重写.forward()MXNet 则对应继承 gluon.Block。两者对应的类定义分别位于 python/mxnet/gluon/nn/basic_layers.pySequential与 python/mxnet/gluon/block.pyBlock。第 3 步损失函数与优化算法本例采用交叉熵损失cross-entropy loss与随机梯度下降SGD# PyTorch pt_loss_fn pt_nn.CrossEntropyLoss() pt_trainer torch.optim.SGD(pt_net.parameters(), lr0.1)# MXNet mx_loss_fn gluon.loss.SoftmaxCrossEntropyLoss() mx_trainer gluon.Trainer(mx_net.collect_params(), sgd, {learning_rate: 0.1})代码差异很小。主要区别是 MXNet 使用 Trainer 类将优化算法作为构造参数传入如sgd并通过 .collect_params() 获取网络全部参数。从源码看Trainer.__init__python/mxnet/gluon/trainer.py接收paramscollect_params()返回的参数字典或列表、optimizer名称与optimizer_params参数字典并支持kvstore、compression_params等分布式与梯度压缩选项collect_params()定义于 python/mxnet/gluon/block.py用于递归收集块内所有Parameter。第 4 步训练循环# PyTorch import time for epoch in range(5): total_loss .0 tic time.time() for X, y in pt_train_data: pt_trainer.zero_grad() loss pt_loss_fn(pt_net(X.view(-1, 28 * 28)), y) loss.backward() pt_trainer.step() total_loss loss.mean() print(epoch %d, avg loss %.4f, time %.2f % ( epoch, total_loss / len(pt_train_data), time.time() - tic))# MXNet from mxnet import autograd for epoch in range(5): total_loss .0 tic time.time() for X, y in mx_train_data: with autograd.record(): loss mx_loss_fn(mx_net(X), y) loss.backward() mx_trainer.step(batch_size128) total_loss loss.mean().item() print(epoch %d, avg loss %.4f, time %.2f % ( epoch, total_loss / len(mx_train_data), time.time() - tic))注意每次运行结果可能有差异因为权重初始化值不同且数据因 shuffle 读取顺序不同。MXNet 侧与 PyTorch 的差异点无需手动展平输入MXNet 前向传入数据时无需像 PyTorch 那样调用X.view(-1, 28*28)将 4-D 输入展平为 2-D。必须在autograd.record()作用域内计算只有记录作用域内的计算才会在反向传播时被自动微分。无需每步清空梯度MXNet 默认grad_reqwrite新梯度直接写入覆盖不会像 PyTorch 那样累积因此不需要trainer.zero_grad()。step()需传批大小MXNet 调用 Trainer.step 时必须指定更新步长通常为 batch size。.item()转标量MXNet 需要调用 .item() 将多维数组转为标量对应 PyTorch 的loss.mean()可直接参与标量运算。原教程提到在此示例中 MXNet 约为 PyTorch 的两倍速度同时强调这类玩具级对比需要谨慎看待不应作为框架性能的定论。深入理解 MXNet 的底层机制autograd作用域式自动微分PyTorch 通过Variable(tensor, requires_gradTrue)包装张量来记录计算图MXNet 则是作用域式记录调用attach_grad()为 NDArray 申请梯度然后在autograd.record()作用域内完成前向计算再调用backward()。# PyTorch x Variable(torch.FloatTensor(1), requires_gradTrue) y x * 2 y.backward() # MXNet x mx.nd.ones((1,)) x.attach_grad() with mx.autograd.record(): y x * 2 y.backward()源码层面record()返回一个_RecordingStateScopepython/mxnet/autograd.py进入with块时通过set_recording(True)开启记录状态、set_training(True)置为训练模式退出时自动恢复先前状态。record(train_modeTrue)的train_mode参数控制 Dropout、BatchNorm 等层在训练/预测模式下的不同行为。作用域覆盖pause、train_mode、predict_mode某些算子Dropout、BatchNorm 等在训练与预测时行为不同MXNet 通过作用域控制x mx.nd.ones((1,)) with autograd.train_mode(): y mx.nd.Dropout(x) with autograd.predict_mode(): z mx.nd.Dropout(y) w mx.nd.ones((1,)) w.attach_grad() with autograd.record(): y x * w y.backward() with autograd.pause(): w w.gradtrain_mode()/predict_mode()仅切换训练/预测行为不改变记录状态python/mxnet/autograd.py 起。pause()用于不需要计算梯度的代码段如测试、I/O、梯度更新其实现为_RecordingStateScope(False, train_mode)python/mxnet/autograd.py。惰性求值与批末同步MXNet 采用惰性求值lazy evaluation以获得更优性能Python 线程只是把操作推入底层引擎engine队列便立即返回算子实际在后台异步执行。因此训练中需要在批末做显式同步例如asnumpy()、wait_to_read()、metric.update(...)等for (data, label) in train_data: with autograd.record(): output net(data) L loss(output, label) L.backward() trainer.step(data.shape[0]) metric.update([label], [output])对应的引擎实现可参见 src/engine如threaded_engine.cc、threaded_engine_pooled.cc其中threaded_engine_pooled.cc使用线程池调度算子、实现依赖感知的异步执行。这也是MXNet 前向/反向会自动排布并行、批末同步后取结果这一编程模型的来源。HybridBlock命令式到符号式的混合HybridBlock同时支持以 Symbol 与 NDArray 前向。hybridize()之后HybridBlock 会把前向计算构建成符号图并缓存。大多数内置块Dense、Conv2D、MaxPool2D、BatchNorm 等都是 HybridBlock类定义位于 python/mxnet/gluon/block.py。net mx.gluon.nn.HybridSequential() net.add(mx.gluon.nn.Dense(10)) net.hybridize()HybridSequential定义于 python/mxnet/gluon/nn/basic_layers.py。混合化后无需显式声明输入数量只需给出输出数量输入形状会在网络首次接收输入时自动推断——这就是partial-shape部分形状信息能力。SymbolBlock从符号图构建块SymbolBlock可从 Symbol 构造块适合把预训练模型用作特征提取器alexnet mx.gluon.model_zoo.vision.alexnet(pretrainedTrue) out alexnet(inputs) internals out.get_internals() outputs [internals[model_dense0_relu_fwd_output]] feat_model gluon.SymbolBlock(outputs, inputs, paramsalexnet.collect_params())API 对照速查附录Tensor 操作对照PyTorch Tensor 与 MXNet NDArray 中函数名不同的对应关系功能PyTorchMXNet Gluon逐元素反余弦x.acos()或torch.acos(x)nd.arccos(x)批量矩阵乘并累加torch.addbmm(M, batch1, batch2)nd.linalg_gemm(M, batch1, batch2)前 n-2 维被归约逐元素除法加缩放再加张量torch.addcdiv(t, v, t1, t2)t v*(t1/t2)矩阵乘并累加torch.addmm(M, mat1, mat2)nd.linalg_gemm(M, mat1, mat2)两向量外积加矩阵m.addr(vec1, vec2)不可用逐元素应用函数x.apply_(callable)不可用但有nd.custom(x, op)逐元素反正弦x.asin()或torch.asin(x)nd.arcsin(x)逐元素反正切x.atan()或torch.atan(x)nd.arctan(x)两张量的反正切x.atan2(y)或torch.atan2(x, y)不可用批量矩阵乘x.bmm(y)或torch.bmm(x, x)nd.linalg_gemm2(x, y)从伯努利分布采样x.bernoulli()不可用用柯西分布填充x.cauchy_()不可用按维度切分张量x.chunk(num_of_chunk)nd.split(x, num_outputsnum_of_chunk)裁剪数值范围x.clamp(min, max)nd.clip(x, min, max)返回副本x.clone()x.copy()叉积x.cross(y)不可用沿轴的累积乘积x.cumprod(1)不可用沿轴的累积和x.cumsum(1)不可用首元素地址x.data_ptr()不可用生成对角张量x.diag()不可用计算张量范数x.dist()nd.norm(x)仅 L2 范数高斯误差函数x.erf()不可用广播到新形状x.expand(3, 4)x.broadcast_to([3, 4])指数分布填充x.exponential_()nd.random_exponential()逐元素取模x.fmod(3)nd.module(x, 3)小数部分x.frac()x - nd.trunc(x)按指定维度 gathertorch.gather(x, 1, torch.LongTensor([[0,0],[1,0]]))nd.gather_nd(x, nd.array([[[0,0],[1,1]],[[0,0],[1,0]]]))最小二乘/最小范数求解B.gels(A)不可用几何分布采样x.geometric_(p)不可用张量所在设备print(x)打印所在设备x.context重复张量x.repeat(4, 2)x.tile(4, 2)张量数据类型x.type()x.dtype散射torch.zeros(2, 4).scatter_(1, torch.LongTensor([[2],[3]]), 1.23)nd.scatter_nd(nd.array([1.23,1.23]), nd.array([[0,1],[2,3]]), (2,4))返回形状x.size()x.shape元素个数x.numel()x.size转为 NumPy ndarrayx.numpy()x.asnumpy()对称矩阵特征分解e, v a.symeig()v, e nd.linalg.syevd(a)转置x.t()x.T均匀分布采样torch.uniform_()nd.sample_uniform()插入新维度x.unsqueeze()nd.expand_dims(x)重塑x.view(16)x.reshape((16,))按指定张量形状查看x.view_as(y)x.reshape_like(y)类型转换副本x.type(type)x.astype(dtype)拷贝值到另一张量dst.copy_(src)src.copyto(dst)指定形状全零张量x torch.zeros(2, 3)x nd.zeros((2, 3))指定形状全一张量x torch.ones(2, 3)x nd.ones((2, 3))同尺寸全一张量y torch.ones_like(x)y nd.ones_like(x)GPU 与跨设备操作与 Tensor 类似MXNet NDArray 可通过指定 context上下文拷贝到 GPU 并在其上运算功能PyTorchMXNet Gluon拷贝到 GPUy torch.FloatTensor(1).cuda()y mx.nd.ones((1,), ctxmx.gpu(0))转成 numpy 数组x y.cpu().numpy()x y.asnumpy()上下文作用域with torch.cuda.device(1):y torch.cuda.FloatTensor(1)with mx.gpu(1):y mx.nd.ones((3, 5))跨多 GPU 拷贝功能PyTorchMXNet Gluon从 GPU 0 拷贝到 GPU 1x torch.cuda.FloatTensor(1)y x.cuda(1)x mx.nd.ones((1,), ctxmx.gpu(0))y x.as_in_context(mx.gpu(1))不同 GPU 间拷贝 Tensor/NDArrayy.copy_(x)x.copyto(y)Autograd 对照功能PyTorchMXNet Gluon记录计算过程x Variable(torch.FloatTensor(1), requires_gradTrue)y x * 2y.backward()x mx.nd.ones((1,))x.attach_grad()with mx.autograd.record():y x * 2y.backward()作用域覆盖不可用x mx.nd.ones((1,))with autograd.train_mode():y mx.nd.Dropout(x)with autograd.predict_mode():z mx.nd.Dropout(y)w mx.nd.ones((1,))w.attach_grad()with autograd.record():y x * wy.backward()with autograd.pause():w w.grad批末同步不可用for (data, label) in train_data:with autograd.record():output net(data)L loss(output, label)L.backward()trainer.step(data.shape[0])metric.update([label], [output])批末同步如asnumpy()、wait_to_read()、metric.update(...)是 MXNet 惰性求值模型下训练循环的必备操作。Module 与 Gluon Block新块定义Gluon 与 PyTorch 高度相似功能PyTorchMXNet Gluon新块定义class Net(torch.nn.Module):def __init__(self, D_in, D_out):super(Net, self).__init__()self.linear torch.nn.Linear(D_in, D_out)def forward(self, x):return self.linear(x)class Net(mx.gluon.Block):def __init__(self, D_in, D_out):super(Net, self).__init__()self.dense mx.gluon.nn.Dense(D_out, in_unitsD_in)def forward(self, x):return self.dense(x)参数与初始化PyTorch 创建层时无需指定参数初始化器各层有默认值Gluon 创建层时可以指定初始化器或留空参数在调用net.initialize(init method)后完成初始化未显式指定初始化器的层会使用传入的init方法。功能PyTorchMXNet Gluon获取全部参数net.parameters()net.collect_params()初始化网络不可用net.initialize(mx.init.Xavier())指定层初始化器layer torch.nn.Linear(20, 10)torch.nn.init.normal(layer.weight, 0, 0.01)layer mx.gluon.nn.Dense(10, weight_initializermx.init.Normal(0.01))已有块的使用几乎一致y net(x)。HybridBlock混合化后允许 partial-shape只给输出数量、输入形状自动推断功能PyTorchMXNet Gluonpartial-shape 混合化不可用net mx.gluon.nn.HybridSequential()net.add(mx.gluon.nn.Dense(10))net.hybridize()Optimizer 与 Gluon Trainer大多数情况下 Gluon API 无需调用zero_grad。zero_grad用于清空所有参数的梯度Gluon 中若grad_req write默认每个 batch 的梯度直接覆盖写入无需手动清空功能PyTorchMXNet Gluon清空梯度optm torch.optim.SGD(model.parameters(), lr0.1)optm.zero_grad()loss_fn(model(input), target).backward()optm.step()trainer gluon.Trainer(net.collect_params(), sgd, {learning_rate: 0.1})with autograd.record():loss loss_fn(net(data), label)loss.backward()trainer.step(batch_size)多 GPU 数据并行功能PyTorchMXNet Gluon数据并行net torch.nn.DataParallel(model, device_ids[0, 1, 2])output net(data)ctx [mx.gpu(i) for i in range(3)]data gluon.utils.split_and_load(data, ctx)label gluon.utils.split_and_load(label, ctx)with autograd.record():losses [loss(net(X), Y) for X, Y in zip(data, label)]for l in losses:l.backward()分布式数据并行功能PyTorchMXNet Gluon分布式数据并行torch.distributed.init_process_group(...)model torch.nn.parallel.distributedDataParallel(model, ...)store kv.create(dist)trainer gluon.Trainer(net.collect_params(), ..., kvstorestore)注意MXNet 的kvstore参数不仅支持dist分布式还支持device、local等模式其实现位于 src/kvstorekvstore_local.h、kvstore_dist.h、kvstore_nccl.h等。训练监控Gluon 提供若干预定义指标metric可在线评估模型性能功能PyTorchMXNet Gluon指标不可用metric mx.metric.Accuracy()with autograd.record():output net(data)L loss(output, label)loss(output, label).backward()trainer.step(batch_size)metric.update(label, output)数据可视化方面PyTorch 常用 TensorboardXMXNet 可用 MXBoard两者 API 风格对应PyTorchMXNetsw tensorboardX.SummaryWriter()sw mxboard.SummaryWriter()......for name, param in model.named_parameters():for name, param in net.collect_params():grad param.clone().cpu().data.numpy()grad param.grad.asnumpy().flatten()sw.add_histogram(name, grad, n_iter)sw.add_histogram(tagstr(param),...valuesgrad,sw.close()bins200,global_stepi)...sw.close()数据加载与序列化Dataset与DataLoader是加载数据的基础组件类PyTorchMXNet Gluon数组数据集torch.utils.data.TensorDataset(data_tensor, label_tensor)gluon.data.ArrayDataset(data_array, label_array)数据加载器torch.utils.data.DataLoader(dataset, batch_size1, shuffleFalse, samplerNone, batch_samplerNone, num_workers0, collate_fnfunction default_collate, drop_lastFalse)gluon.data.DataLoader(dataset, batch_sizeNone, shuffleFalse, samplerNone, last_batchkeep, batch_samplerNone, batchify_fnNone, num_workers0)顺序采样器torch.utils.data.sampler.SequentialSampler(data_source)gluon.data.SequentialSampler(length)随机采样器torch.utils.data.sampler.RandomSampler(data_source)gluon.data.RandomSampler(length)计算机视觉常用数据集由mx.gluon.data.vision包提供源码见 python/mxnet/gluon/data/vision类PyTorchMXNet GluonMNISTtorchvision.datasets.MNISTmx.gluon.data.vision.MNISTCIFAR10torchvision.datasets.CIFAR10mx.gluon.data.vision.CIFAR10CIFAR100torchvision.datasets.CIFAR100mx.gluon.data.vision.CIFAR100文件夹图像加载器torchvision.datasets.ImageFolder(root, transformNone, target_transformNone, loaderfunction default_loader)mx.gluon.data.vision.ImageFolderDataset(root, flag, transformNone)序列化与反序列化通过save_parameters与load_parameters完成类PyTorchMXNet Gluon保存模型参数torch.save(the_model.state_dict(), filename)model.save_parameters(filename)加载参数the_model.load_state_dict(torch.load(PATH))model.load_parameters(filename, ctx, allow_missingFalse, ignore_extraFalse)结论如上所见Apache MXNet 的 Gluon API 与 PyTorch 存在大量相似之处。核心差异集中在两点术语Tensor vs NDArray与梯度累积行为PyTorch 中梯度累积、MXNet 中梯度覆盖写入。其余代码结构高度对应将代码从一个框架迁移到另一个框架非常直接。推荐下一步Gluon API 与 PyTorch 相似之外还提供了一些让代码更快的能力阅读 Hybridize 教程学习如何编写可转换为符号式的命令式代码。阅读 自定义层教程了解如何用自定义层扩展 MXNet。赞分享人工智能深度学习机器学习【免费下载链接】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点击查看免费下载相关推荐从原生 Selenium 迁移到 SeleniumBase五阶段演进实战与底层原理对照从原生 Selenium 迁移到 SeleniumBase五阶段演进实战与底层原理对照 本文以 SeleniumBase 仓库中的 examples/migr测试网页爬虫RPA如何在15分钟内完成黑苹果配置OpCore-Simplify智能EFI构建指南如何在15分钟内完成黑苹果配置OpCore Simplify智能EFI构建指南 还在为复杂的黑苹果配置而头疼吗OpCore Simplify是你的终极解决方深度学习人工智能机器学习分布式训练PyTorch与MXNet/Gluon深度学习框架全方位对比从入门到迁移实战指南PyTorch与MXNet/Gluon深度学习框架全方位对比从入门到迁移实战指南 引言框架选型的终极难题 你是否在PyTorch与MXNet/Gluon之间创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

汽车EMC设计实战:从原理到整改的完整指南

汽车EMC设计实战:从原理到整改的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 14:03:36 阅读更多 →
别找临时中转:Roo Code 的兼容通道选 TaoToken,用 MiniMax M3 跑补丁

别找临时中转:Roo Code 的兼容通道选 TaoToken,用 MiniMax M3 跑补丁

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/21 17:56:12 阅读更多 →
10 分钟用 TaoToken 跑通 mcp-server-fetch 的抓取技能

10 分钟用 TaoToken 跑通 mcp-server-fetch 的抓取技能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/20 11:29:01 阅读更多 →

最新新闻

2026年9月前端开发AI编程工具对比测评:Copilot、Cursor、通义灵码等六款实测

2026年9月前端开发AI编程工具对比测评:Copilot、Cursor、通义灵码等六款实测

1. 前端开发选AI编程工具,先搞清楚你到底在选什么前端开发这个行当,这两年最大的变量不是框架更新,也不是构建工具换代,而是AI编程工具直接杀进了日常写代码的流程里。2026年9月这个时间节点往回看,市面上能叫得出名字…

2026/9/21 18:15:17 阅读更多 →
身份证有效期查询保姆级教程:从正则到实战的底层逻辑

身份证有效期查询保姆级教程:从正则到实战的底层逻辑

身份证有效期查询保姆级教程:从正则到实战的底层逻辑 别再说你会写代码就能找工作了。我见过太多应届生,LeetCode 刷得飞起,Python…

2026/9/21 18:15:17 阅读更多 →
Java项目集成Jetpack五件套:Room+ViewModel+LiveData+DataBinding实践

Java项目集成Jetpack五件套:Room+ViewModel+LiveData+DataBinding实践

入行 Android 久了你会发现,本地数据存储这块儿特别能检验一个项目的设计功底。早几年我写 SQLite 查询,SQLiteOpenHelper、游标、DAO helper 类来回倒腾,版本升级一不注意就崩,配置变更转个屏数据就没了,后来 Jetpack…

2026/9/21 18:15:17 阅读更多 →
Vue3 + NaiveUI 表格合并 rowSpan 实战:从原理到完整实现

Vue3 + NaiveUI 表格合并 rowSpan 实战:从原理到完整实现

做后台管理系统这几年,最常被测试和产品追着改的,除了按钮样式,就是表格。尤其是“这一列内容重复了,能不能合并一下”“像 Excel 那样把相同项合并了”这类需求,几乎每个项目都会碰到。如果你用的是 Vue 3 搭配 Naive…

2026/9/21 18:15:17 阅读更多 →
微信小程序直播带货商品数据分析系统:从数据采集到实时看板全链路拆解

微信小程序直播带货商品数据分析系统:从数据采集到实时看板全链路拆解

干这行的人都知道,一场直播下来,数据复盘才是最磨人的环节。平台后台给的是宏观数字,想要按商品维度、按分钟趋势、按渠道来源拆,基本做不到。这套基于微信小程序的直播带货商品数据分析系统,解决的就是这个痛点&#…

2026/9/21 18:15:17 阅读更多 →
心理学现象避坑指南:面试高频考点拆解与实战代码

心理学现象避坑指南:面试高频考点拆解与实战代码

心理学现象避坑指南:面试高频考点拆解与实战代码 刚把网上抄的代码往本地一粘,直接报错?别慌,这不仅是环境问题,更是你对底层逻辑理解不够。很多培训机构学员在准备面试时,容易陷入“背八股文”的误区,以为只要记住定义就能过关。但现实是,大厂面试官…

2026/9/21 18:14:15 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/21 15:36:51 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/21 15:36:51 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →