Python打卡第34天

@浙大疏锦行

作业:

loss.item() 虽然只在 CPU 中执行,但它会触发一次 GPU → CPU 的强制同步,这是影响性能的关键!

loss.item() 做了什么?

  1. 数据原本在 GPU 上
  • 训练时,loss 是一个 GPU 上的张量(比如 torch.cuda.FloatTensor)。

  • GPU 可以高效计算,但 不能直接读取数值(就像工厂生产产品,但你要亲自去工厂拿货)。

  1. .item() 的本质
  • loss.item() 做了 3 件事:

    1. 暂停 GPU 计算:强制 GPU 停下当前所有任务(同步点)。

    2. 把数据从 GPU 复制到 CPU(通过 PCIe 总线,就像用卡车从工厂运货到商店)。

    3. 转换成 Python 数字(floatint),因为 Python 只能处理 CPU 数据。

  1. 为什么这么慢?
  • 不是 .item() 本身慢,而是 GPU→CPU 的传输和同步慢!

  • 每次调用 .item(),GPU 都要:

    • 等所有并行计算完成(比如 1000 个 CUDA 核心都要停)。

    • 走 PCIe 总线(带宽有限,延迟高)。

    • 等 CPU 确认收到数据后才能继续计算。

__call__方法

在 Python 中,call 方法是一个特殊的魔术方法(双下划线方法),它允许类的实例像函数一样被调用。这种特性使得对象可以表现得像函数,同时保留对象的内部状态。

比如:

python 复制代码
# 不带参数的call方法
class Counter:
    def __init__(self):
        self.count = 0
    
    def __call__(self):
        self.count += 1
        return self.count

# 使用示例
counter = Counter()
print(counter())  # 输出: 1
print(counter())  # 输出: 2
print(counter())  # 输出: 3
print(counter.count)  # 输出: 3
python 复制代码
1
2
3
3
python 复制代码
# 带参数的call方法
class Adder:
    def __call__(self, a, b):
        print("唱跳篮球rap")
        return a + b

adder = Adder()
print(adder(3, 5))  # 输出: 8
python 复制代码
唱跳篮球rap
8

为什么 PyTorch 要用 __call__ 而不是直接暴露 forward

  1. 封装性:__call__ 可以统一管理 forward 前后的逻辑(如自动梯度、Hook 机制)。

  2. 安全性:防止用户直接调用 forward 导致梯度丢失或计算图断裂。

  3. 一致性:让所有模块(nn.Linearnn.Conv2d、自定义模型)都能用 module(x) 的方式调用。

相关推荐
ai_xiaogui11 分钟前
一键部署AI工具!用AIStarter快速安装ComfyUI与Stable Diffusion
人工智能·stable diffusion·部署ai工具·ai应用市场教程·sd快速部署·comfyui一键安装
Tipriest_16 分钟前
Python关键字梳理
python·关键字·keyword
聚客AI1 小时前
Embedding进化论:从Word2Vec到OpenAI三代模型技术跃迁
人工智能·llm·掘金·日新计划
weixin_387545641 小时前
深入解析 AI Gateway:新一代智能流量控制中枢
人工智能·gateway
im_AMBER2 小时前
学习日志05 python
python·学习
大虫小呓2 小时前
Python 处理 Excel 数据 pandas 和 openpyxl 哪家强?
python·pandas
聽雨2372 小时前
03每日简报20250705
人工智能·社交电子·娱乐·传媒·媒体
哪 吒2 小时前
2025B卷 - 华为OD机试七日集训第5期 - 按算法分类,由易到难,循序渐进,玩转OD(Python/JS/C/C++)
python·算法·华为od·华为od机试·2025b卷
二川bro2 小时前
飞算智造JavaAI:智能编程革命——AI重构Java开发新范式
java·人工智能·重构
acstdm2 小时前
DAY 48 CBAM注意力
人工智能·深度学习·机器学习