深度学习任务运行数小时后,突然因损坏图片、空标注或异常尺寸报错,是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训练坏样本自动定位:避免任务跑几小时后突然中断》 是转载文章,点击查看原文。