当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > PyTorch 怎样用 autocast 控制混合精度范围

PyTorch 怎样用 autocast 控制混合精度范围

来源:17golang原创 2026-11-07 23:18:43 0浏览 收藏

如果你想让 PyTorch 的混合精度只覆盖模型前向和损失计算,核心写法就是把这两部分放进 torch.autocast,然后在上下文外执行反向传播和参数更新。这样既能让 autocast 自动为适合的算子选择低精度,也能把需要稳定精度的局部计算单独切回 float32。

官方地址:https://pytorch.org/

记住一个边界:autocast 管前向计算的精度选择,GradScaler 管训练梯度的缩放;backward() 通常放在 autocast 外,推理则只需要 autocast,不需要 GradScaler。
  • 训练:autocast 包住前向与 loss,退出后再 backward、step、update。
  • 推理:只包住模型前向和必要的后处理,不创建 GradScaler。
  • 局部稳定性:在外层 autocast 内用 enabled=False 创建 float32 子域。
  • 判断依据:显式指定 dtype 的算子、原地操作和 out= 形式不会按普通可自动转换算子处理。

先把 autocast 的边界放对

在一个常见的训练回合里,模型前向和损失计算是 autocast 最合适的作用域。它会根据算子类型选择低精度或 float32,而不是把整个 Python 函数强行转换成同一种 dtype。反向传播依赖前向期间形成的计算图,因此通常在退出 autocast 后调用。

import torch

# autocast 只包住前向和损失计算,退出后再做反向传播
with torch.autocast(device_type="cuda", dtype=torch.float16):
    logits = model(inputs)
    loss = loss_fn(logits, targets)

# 训练更新不放进 autocast,保持职责边界清楚
loss.backward()
optimizer.step()
optimizer.zero_grad(set_to_none=True)

这里的关键不是把上下文写得越大越好,而是让它围绕“需要自动选择算子精度的前向区域”。把数据读取、优化器更新或无关的日志逻辑塞进上下文,不会让训练更可靠,反而会让 dtype 归属变得难以判断。

PyTorch autocast 前向计算域与训练更新域的静态结构说明图
图1:autocast 前向计算域的静态说明图,展示模型、损失与训练更新的职责边界,不是运行截图。

设备和任务不同,dtype 也要明确

使用新式接口时,把设备类型写在 torch.autocast 参数中更直观。CUDA 训练常见的是 float16,CPU 场景常见的是 bfloat16;实际选择仍要结合设备支持和模型的数值稳定性。

import torch

device = "cuda" if torch.cuda.is_available() else "cpu"
model = model.to(device)
inputs = inputs.to(device)

# CUDA 示例:只让当前前向区域采用混合精度
with torch.autocast(device_type="cuda", dtype=torch.float16):
    logits = model(inputs)

# CPU 示例:CPU 设备使用 bfloat16 时,单独写清作用域
with torch.autocast(device_type="cpu", dtype=torch.bfloat16):
    logits = model(inputs)

# 不要把两个设备示例同时放进同一个真实训练回合
print(logits.dtype)  # 用于观察示例张量的 dtype,不代表所有算子都相同

上面的两个上下文是互斥示例。实际代码应根据输入张量和模型所在设备选择其中一个,避免把设备字符串、输入位置和 autocast 配置写成三套互不相干的状态。

需要稳定计算时,用嵌套作用域切回 float32

有些敏感计算需要 float32 的动态范围。此时不用取消整个外层 autocast,而是在局部建立 enabled=False 的子域,并把传入该子域的浮点输入显式转为 float32。这样边界清楚,其他前向算子仍可继续使用外层的自动转换。

import torch

with torch.autocast(device_type="cuda", dtype=torch.float16):
    features = encoder(inputs)

    # 局部关闭 autocast,敏感算子使用 float32 输入和计算
    with torch.autocast(device_type="cuda", enabled=False):
        stable_features = features.float()
        stable_score = sensitive_op(stable_features)

    # 子域结束后回到外层 autocast 的前向区域
    loss = loss_fn(stable_score, targets)

# backward 仍在 autocast 外部执行
loss.backward()

注意,关闭 autocast 不会自动把已经得到的张量变成 float32,所以 features.float() 是这个边界中的重要动作。子域只应覆盖真正需要稳定精度的计算,范围过大就会失去混合精度的收益。

PyTorch 嵌套 autocast 与局部 float32 子域的静态结构说明图
图2:嵌套 autocast 与局部 float32 子域的静态说明图,展示职责关系,不是运行截图。

训练时怎样接上 GradScaler

对使用 float16 的训练,autocast 与 torch.amp.GradScaler 是两个独立组件:前者负责前向算子的 dtype 选择,后者负责缩放 loss 和梯度,降低小梯度下溢的风险。一个最小训练骨架如下。

import torch

# scaler 在一次完整训练过程中复用,不要每个 batch 都重新创建
scaler = torch.amp.GradScaler("cuda")

for inputs, targets in train_loader:
    inputs = inputs.cuda(non_blocking=True)
    targets = targets.cuda(non_blocking=True)
    optimizer.zero_grad(set_to_none=True)

    # 前向与 loss 在 autocast 内部计算
    with torch.autocast(device_type="cuda", dtype=torch.float16):
        logits = model(inputs)
        loss = loss_fn(logits, targets)

    # 缩放、反向、更新各自承担不同职责
    scaler.scale(loss).backward()
    scaler.step(optimizer)
    scaler.update()

如果要在更新前裁剪梯度,先对对应优化器调用 scaler.unscale_(optimizer),再执行裁剪;同一个优化器在一次 step 间隔内不要重复 unscale。梯度累积时,也要等一个有效 batch 的梯度积累完成后再统一 unscale、step 和 update。

推理、原地操作和编译场景的几个边界

推理或评估只需要用 autocast 包住前向,不需要 GradScaler。训练与推理可以共享模型,但作用域和更新步骤不能混写。

import torch

model.eval()
with torch.inference_mode():
    # 推理没有 backward 和 optimizer.step,因此不需要 GradScaler
    with torch.autocast(device_type="cuda", dtype=torch.float16):
        predictions = model(inputs)

return predictions

另外,显式传入 dtype= 的算子不会按普通 autocast 规则重新选择 dtype;原地变体和带 out= 的调用也不走同样的自动转换路径。遇到 dtype 与预期不符时,先检查这三类写法,再确认是否把张量送到了正确设备。

如果把 AMP 和 torch.compile 组合使用,还要注意编译反向传播对 autocast 上下文的假设。保持“前向与 loss 在 autocast 内、backward 在外”的结构,并按 PyTorch 编译器文档确认 backward_pass_autocast 的配置与实际训练方式一致。

一张表记住作用域判断

场景autocast 范围是否需要 GradScaler
float16 训练前向与 loss通常需要
float16 推理模型前向与必要后处理不需要
敏感算子外层 autocast 内嵌套 enabled=False按训练或推理场景决定
反向传播放在 autocast 外训练时按缩放方案调用
参数更新放在 autocast 外训练时由 scaler.step 或 optimizer.step 负责

常见问题

autocast 要不要包住 backward?

通常不要。推荐把前向和损失计算放入 autocast,退出后再 backward;反向算子会沿用前向阶段相关的 dtype 选择。

局部关闭 autocast 后为什么还要调用 float()?

enabled=False 只关闭该区域的自动转换,不会替已经是低精度的输入自动升为 float32。敏感算子需要稳定精度时,应显式转换传入张量。

推理也要创建 GradScaler 吗?

不需要。没有梯度和参数更新时,autocast 足够完成推理阶段的混合精度控制。

为什么某个算子没有按预期转换?

检查它是否显式指定了 dtype、是否使用原地调用或 out= 参数,再检查当前 autocast 的 device_type 和上下文是否覆盖了该调用。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Hugging Face Spaces 怎样查看应用运行日志Hugging Face Spaces 怎样查看应用运行日志
上一篇
Hugging Face Spaces 怎样查看应用运行日志
MLflow 模型别名怎样把新版本切换到 champion 并支持回滚
下一篇
MLflow 模型别名怎样把新版本切换到 champion 并支持回滚
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    932次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    937次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1046次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1016次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    844次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码