You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pytorch MPS超参调优时触发'mps.scatter_nd'张量形状错误

MPS设备下超参数调优第二次训练失败的解决方案

问题背景

使用NeverGrad为SASRec模型搭建超参数调优流程时,首次训练可正常完成,但第二次训练启动时触发MPS设备报错:

MetalPerformanceShadersGraph/mpsgraph/MetalPerformanceShadersGraph/Core/Files/MPSGraphUtilities.mm":49:0)): error: 'mps.scatter_nd' op invalid input tensor shape: updates tensor shape and data tensor shape must match along inner dimensions
/AppleInternal/Library/BuildRoots/97f6331a-ba75-11ed-a4bc-863efbbaf80d/Library/Caches/com.apple.xbs/Sources/MetalPerformanceShadersGraph/mpsgraph/MetalPerformanceShadersGraph/Core/Files/MPSGraphExecutable.mm:1710: failed assertion `Error: MLIR pass manager failed'

仅MPS设备出现该问题,CPU设备运行完全正常,模型本身无逻辑错误。

核心原因与解决方案

1. 清理MPS残留资源

MPS设备在训练结束后可能残留未释放的张量或计算图状态,导致下一次训练时张量形状不匹配。在main函数末尾添加资源清理逻辑:

# 清理MPS缓存
torch.mps.empty_cache()
# 将模型移回CPU,彻底释放MPS设备资源
model.to('cpu')

同时在objective函数中,每次调用main后也执行清理:

def objective(hyperparameters):
    # ... 原有参数赋值代码 ...
    hit_10 = main(args)
    # 训练后立即清理MPS资源
    torch.mps.empty_cache()
    return -hit_10

2. 避免全局args对象的状态污染

当前代码直接修改全局args对象的属性,不同trial间可能存在参数残留。改为创建args副本进行操作:

def objective(hyperparameters):
    # 创建args副本,隔离不同trial的参数状态
    trial_args = argparse.Namespace(**vars(args))
    
    trial_args.dropout_rate = hyperparameters["dropout_rate"]
    trial_args.maxlen = int(hyperparameters["maxlen"])
    trial_args.lr = hyperparameters["lr"]
    trial_args.hidden_units = hyperparameters["hidden_units"]

    n_heads_max = trial_args.hidden_units // 2
    var_heads = [i for i in range(1, n_heads_max + 1) if trial_args.hidden_units % i == 0]
    trial_args.num_heads = hyperparameters["num_heads"] % len(var_heads)
    trial_args.num_heads = var_heads[trial_args.num_heads]

    trial_args.num_blocks = int(hyperparameters["num_blocks"])

    hit_10 = main(trial_args)
    torch.mps.empty_cache()
    return -hit_10

3. 修复WarpSampler的多线程残留

WarpSampler的多线程可能在MPS设备下残留未终止的线程资源,修改main函数中的sampler关闭逻辑:

# 在main函数末尾
sampler.close()
# 等待所有线程完全终止
import time
time.sleep(1)
torch.mps.empty_cache()

4. 禁用WandB设备同步(可选)

WandB的自动设备跟踪可能保留MPS张量引用,导致资源无法释放。初始化WandB时添加禁用配置:

wandb.init(
    project='SASRec_RND', 
    config=args, 
    settings=wandb.Settings(_disable_device_sync=True)
)

内容的提问来源于stack exchange,提问作者mckris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 06:12:05