PyTorch训练坏样本自动定位:避免任务跑几小时后突然中断

作者:ai小陈日期:2026/9/11

深度学习任务运行数小时后,突然因损坏图片、空标注或异常尺寸报错,是GPU算力平台上的高频问题。此时GPU本身通常没有故障,真正原因是数据集没有在训练前完成校验。本文以PyTorch为例,搭建“预扫描—运行捕获—隔离清单—复核修复”的坏样本定位流程。

一、问题背景

常见异常包括图片无法解码、标签越界、文本编码错误、输入包含NaN,以及不同样本Shape无法组成Batch。小规模调试可能碰不到这些文件,大模型训练或长周期深度学习实验一旦随机读取到坏样本,整个进程就可能退出。

GPU服务器租用往往按使用时间计费。让高性能GPU等待CPU重复读取坏文件,不仅浪费时间,还会使实验难以复现。推理部署前的数据清洗同样重要,错误输入应在进入模型前被拦截。

二、环境准备

准备Linux、Python、PyTorch、Pillow和独立日志目录:

1pip install torch pillow
2mkdir -p logs quarantine
3nvidia-smi
4

Python 3.12 + CUDA 12.8开发镜像,包含Ubuntu 24.04、JupyterLab和SSH,并支持安装PyTorch、JAX等框架。可通过官网查看当前GPU云服务器与镜像资源。

三、实操步骤

步骤1:训练前扫描文件

1from pathlib import Path
2from PIL import Image
3
4bad = []
5for path in Path("dataset/images").rglob("*"):
6    if not path.is_file():
7        continue
8    try:
9        with Image.open(path) as img:
10            img.verify()
11    except Exception as e:
12        bad.append((str(path), repr(e)))
13
14with open("logs/bad_images.tsv", "w", encoding="utf-8") as f:
15    for path, error in bad:
16        f.write(f"{path}\t{error}\n")
17

verify()适合快速检查文件结构,但不等于完整解码。正式处理前可再次执行convert("RGB")load(),确认像素数据可读。

步骤2:校验标签范围

1def check_label(label, num_classes):
2    if not isinstance(label, int):
3        raise TypeError(f"label type: {type(label)}")
4    if not 0 <= label < num_classes:
5        raise ValueError(f"label out of range: {label}")
6

检测任务还应检查边界框坐标、宽高是否为正,以及标注是否超出图片范围。文本任务则要检查空内容、编码和超长样本。

步骤3:返回样本路径

Dataset除张量和标签外,同时返回源文件路径:

1def __getitem__(self, index):
2    path, label = self.samples[index]
3    image = Image.open(path).convert("RGB")
4    return self.transform(image), label, str(path)
5

当Loss出现NaN或Shape异常时,日志可以直接定位原始文件,不必根据随机索引反推。

步骤4:捕获运行阶段异常

1for step, batch in enumerate(loader):
2    try:
3        images, labels, paths = batch
4        if not torch.isfinite(images).all():
5            raise ValueError(f"non-finite input: {paths}")
6        loss = train_step(images.cuda(), labels.cuda())
7    except Exception:
8        logger.exception("failed step=%s", step)
9        raise
10

训练阶段建议记录后终止,而不是静默跳过。无条件跳过会改变数据分布,也可能掩盖系统性标注问题。

步骤5:建立隔离清单

不要立即删除坏文件。把路径、异常类型、发现时间和处理状态写入清单,再由数据负责人确认修复、替换或排除。迁移到其他AI算力平台时,应同步数据版本和隔离清单,确保输入一致。

步骤6:小规模回归

修复后先使用单进程DataLoader遍历全量数据,再逐步恢复多进程和数据增强。最后运行固定训练步数,对比样本数、Loss和吞吐,确认没有引入新的异常。

四、常见问题

1. num_workers大于0时看不到准确报错

先设置num_workers=0复现,异常会直接回到主进程,便于查看完整堆栈。

2. 图片能打开但训练仍报错

可能是颜色通道、尺寸、增强操作或标注不匹配,应检查转换后的张量Shape。

3. 是否可以自动跳过坏样本

探索阶段可以临时跳过,但正式训练应保留统计,并确认不会造成类别偏差。

4. 多GPU怎样记录问题样本

日志中加入Rank、Step和路径,避免多个进程同时写入同一文件造成覆盖。

五、总结

坏样本排查应在GPU计算前完成:先扫描文件,再验证标签,训练时保留路径,最后用隔离清单管理修复。润云智算提供按需GPU资源和开发镜像,可支持科研训练、大模型训练与推理部署;无论选择哪种AI算力平台,稳定任务都应从可追溯的数据输入开始。

FAQ

Q1:训练前扫描会不会很慢?

会产生一次读取成本,但通常远低于长任务中途失败后的重算成本。

Q2:PIL verify通过就一定正常吗?

不一定,还应执行完整解码并验证转换后的张量。

Q3:坏样本应该删除吗?

建议先隔离并记录原因,确认无法修复后再从训练清单中排除。

Q4:如何保证数据版本一致?

保存文件清单、哈希、标注版本和隔离记录,并与实验配置一起归档。


PyTorch训练坏样本自动定位:避免任务跑几小时后突然中断》 是转载文章,点击查看原文


相关推荐


【AI】大模型本地部署与量化:Ollama、transformers、llama.cpp实践
漂流瓶jz2026/9/3

部署即在本地电脑中下载并运行模型,就像使用网络上的大模型API一样,但区别在于模型是运行在本地的,不收费也不会泄露信息。但模型可能很大,本地电脑可能会内存不足,这时候就需要量化来尝试缩小模型存储空间,同时尽量避免模型性能损失。 Ollama Ollama是一个大模型部署工具,用它只需要执行几个命令,就可以在本地电脑下载和部署大模型。官网列出了非常多可以部署的模型,有官方模型,也有用户训练/调整过的模型。 使用Ollama部署 首先安装Ollama本身,然后执行命令行。这里我们以Qwen3:0.6


本体论的基本核心概念
Shawn_Shawn2026/8/26

核心概念 Ontology(本体) 本体不是某一张表,而是整个组织共享的语义模型:它定义了企业里有哪些实体类型、实体有哪些属性、实体之间如何关联、可以对实体执行哪些操作。 在许多应用场景中,本体充当了组织的“数字孪生”(Digital Twin),兼具支持各类用例所需的语义元素(对象、属性、链接)和动力学元素(操作、函数、动态安全管控)。 对象类型(Object type) 定义了组织中的一个实体或事件。 属性(Property) 定义了对象类型的特征。 链接类型(Link type) 定义了


uni-app 三方库与插件管理体系全解析:从原生开发者视角彻底讲透
90后晨仔2026/8/13

作者视角: 本文面向从 iOS/Android/鸿蒙原生开发转型 uni-app 跨端开发的工程师。你习惯了 CocoaPods、Gradle、OHPM 那套成熟的包管理体系,来到 uni-app 后大概率会困惑: "我的依赖到底该放哪?谁管版本?谁解析传递依赖?" 这篇文章将一次性把这些困惑讲透。 一、为什么 uni-app 的依赖管理"看起来复杂"? 1.1 原生世界的"一平台一管家" 在纯原生开发中,每个平台有唯一、权威的包管理器:


CentOS Stream 9 Redis 7.2.7 源码编译一键安装脚本
☆凡尘清心☆2026/8/4

CentOS Stream 9 Redis 7.2.7 源码编译一键安装脚本 自动编译、自动配置、自动 systemd 托管开启 AOF 持久化 + 密码 + 远程访问安装完直接可用 #!/bin/bash set -euo pipefail # 版本与路径 REDIS_VERSION="7.2.7" INSTALL_DIR="/usr/local/redis" DATA_DIR="/data/redis" LOG_DIR="/var/log/redis" CONF_DIR="${INSTA


我用 AI Agent 重构了日常开发工作流,效果出乎意料
吴琼琼2026/7/27

我用 AI Agent 重构了日常开发工作流,效果出乎意料 写代码 5 年,我第一次觉得 AI 不只是「自动补全」 前言 不知道你有没有这种感觉——AI 编程工具用了一堆,但总觉得差点意思。 GitHub Copilot 帮你补全代码,但补完你还是要自己调试。Cursor 让你和 AI 聊天,但聊完你还是要自己改。ChatGPT 给你写函数,但写完你还得自己组装。 这些工具更像是一个「超级自动补全」,而不是一个「真正的开发者」。 直到我开始尝试 AI Agent——让你的 AI 不再是只会回


从暴力到滑动窗口的终极形态:力扣3「无重复字符的最长子串」的优化进化之路
胡萝卜术2026/7/19

从暴力到滑动窗口的终极形态:力扣3「无重复字符的最长子串」的优化进化之路 当我们从数组和链表的“冰冷内存”转向字符串的“流式字符”时,滑动窗口才真正展现出它最优雅的一面。这道题,就是滑动窗口思想的“封神之作”。 前言 在连续攻克了链表专题的重重关卡——从反转链表(206)到LRU缓存(146)——之后,是时候进入一个全新的数据结构领域了。今天,我们首先要面对的,是字符串/数组专题中最经典、最基础、也是面试中出现频率最高的题目之一——力扣3. 无重复字符的最长子串(Longest Substr


MCP 入门实战:写一个能读本地文件的极简服务
To_OC2026/7/11

前几天折腾 AI IDE 的时候,一直有个特别烦人的痛点:大模型只能跟你聊代码逻辑,没法直接读我本地的项目文件。每次想让它帮我看个配置、改个脚本,都得手动复制一大段内容粘贴进去,文件长了特别折腾。 直到我看到有人提 MCP,说能让大模型直接调用本地工具。我寻思不就是读个文件嘛,应该不难,索性自己动手写个最简单的文件读取 MCP 服务。结果真上手才发现,坑全在细节里,折腾了小半天才跑通。今天顺着我当时的思路捋一遍,省得后面有人跟我一样走弯路。 先搞懂:MCP 到底在中间干了啥 说实话,最开始我对


Gson → kotlinx.serialization
plainGeek2026/7/3

Gson → kotlinx.serialization 老写法(Java + Gson) Gson gson = new Gson(); // 序列化 Item item = new Item(1, "商品", 9.99); String json = gson.toJson(item); // 反序列化 Item parsed = gson.fromJson(json, Item.class); List<Item> list = gson.fromJson(jsonArray,


图解 MongoDB 12|索引与查询优化地图:一条主线,三个判断轴
十三Tech2026/6/25

到这里,索引与查询优化这个阶段就讲完了。从第 04 篇的索引模型,到第 11 篇的慢查询排查闭环,中间穿过了索引类型、ESR 原则、explain、覆盖查询。这些不是孤立的知识点,而是一条连贯的主线——每一步都在回答「怎么让查询又快又省」。 这一篇是阶段的收束,不引入新机制,而是把前面讲过的东西收成一张地图和三个判断轴,方便你在实际工作中快速调用。后面进入存储引擎与内存阶段(13–17)时,会从「查询怎么用索引」下沉到「索引和数据怎么在内存里」。 一条主线 这条主线有六个节点,对应这个阶段的六


Vue集成uuid生成唯一标识实践指南
独泪了无痕2026/6/16

一、核心基础 1.1 UUID 是什么   UUID(通用唯一标识符,Universally Unique Identifier) 是一个 128 位用于标识信息的唯一标识符,通常以 32 个十六进制的字符串形式呈现,具有全球唯一性(理论上重复概率可忽略),非常适合用于标识网络中的资源、数据记录或其他任何需要唯一标识的实体。 UUID 生成器:devtool.tech/uuid 1.2 uuid.js 库概述   uuid.js 是用于生成 UUID 的 JavaScript 库,解决

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读