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

PyTest运行加载FastAI模型时出现AttributeError:找不到my_func

解决PyTest环境中加载FastAI模型时的AttributeError问题

问题原因

直接用python3运行测试脚本时,脚本以__main__模块身份执行,你导入的my_func存在于这个__main__命名空间中,因此FastAI加载模型时(底层用torch pickle反序列化)能找到该函数。

但用pytest运行时,测试脚本会被作为pytest.__main__模块执行,你导入的my_func实际存在于tests.test_predict模块命名空间,而非pytest.__main__,导致pickle反序列化时找不到函数,抛出AttributeError。

解决方案

方案1:将自定义函数注入pytest的__main__命名空间

在测试脚本开头,导入my_func后,显式把它添加到pytest.__main__的模块命名空间中:

import pytest
import sys
from fastai.vision.all import *
from project.predict import my_func, prediction

# 把my_func注入到pytest.__main__命名空间
sys.modules['pytest.__main__'].my_func = my_func

model = load_learner('model_path/', cpu=True)
model.load(fast_ai_params.weights)

def my_test():
    pred = prediction(tile_params, model, full_tile_path)
    assert pred.shape

方案2:用Pytest Fixture延迟模型加载(推荐)

将模型加载逻辑放到Pytest Fixture中,避免在模块级别执行,同时确保函数所在模块的命名空间被正确识别:

import pytest
import sys
from fastai.vision.all import *
from project.predict import my_func, prediction

# 确保my_func所在的模块被pickle识别
import project.predict
sys.modules['project.predict'] = project.predict

@pytest.fixture(scope="module")
def trained_model():
    learner = load_learner('model_path/', cpu=True)
    learner.load(fast_ai_params.weights)
    return learner

def my_test(trained_model):
    pred = prediction(tile_params, trained_model, full_tile_path)
    assert pred.shape

这种方式不仅解决了命名空间问题,还能利用Fixture的作用域复用模型实例,提升测试效率。

方案3:修改模型保存时的函数引用(根源解决)

如果有权限重新训练保存模型,可以在训练时确保my_func被绑定到固定模块(而非__main__)。比如在训练脚本中,不要在__main__里定义my_func,而是把它放到project.predict模块中,然后从该模块导入使用,再保存模型。这样后续加载时,pickle会直接去project.predict模块找函数,不会受运行环境的命名空间影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:55:15