Autodl上传大数据集太慢?分片压缩与断点续传实战指南

1次阅读
没有评论

共计 1906 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景痛点:为什么原生上传这么慢?

最近在 Autodl 平台上传一个 200GB 的 CV 数据集时,发现原生上传工具经常卡死,速度波动在 5 -10MB/s,总耗时超过 6 小时。经过抓包分析发现三个关键瓶颈:

Autodl 上传大数据集太慢?分片压缩与断点续传实战指南

  1. 单线程传输 :原生工具未利用多线程并发,网络带宽利用率不足 30%
  2. 无断点续传 :网络波动会导致整个文件重传
  3. 内存膨胀 :大文件直接加载导致频繁触发 GC

技术方案设计

分片策略:化整为零

  • 将数据集按 500MB 分片(实测平衡了 IOPS 和并发效率)
  • 每个分片独立压缩上传,避免单点故障
  • 分片命名规则: 数据集名_序号. 分片后缀 (如 coco_001.zstd

压缩算法选型

对比测试三种常用算法(压缩级别统一设为 3):

算法 压缩速度 (MB/s) 解压速度 (MB/s) 压缩率
zstd 420 520 2.8:1
lz4 550 3000 2.1:1
gzip 180 220 3.1:1

最终选择 zstd:在压缩率和速度间取得较好平衡

代码实现

分片生成核心代码

import shutil
from pathlib import Path

def split_file(input_path, chunk_size=500*1024*1024):
    """
    参数说明:chunk_size: 基于 SSD 随机读写性能,建议设置在 200MB-1GB 之间
    """with open(input_path,'rb') as f:
        chunk_num = 0
        while True:
            chunk_data = f.read(chunk_size)
            if not chunk_data:
                break

            chunk_path = f"{input_path.stem}_{chunk_num:03d}.zstd"
            with open(chunk_path, 'wb') as chunk_file:
                chunk_file.write(chunk_data)
            chunk_num += 1

多线程上传控制

from concurrent.futures import ThreadPoolExecutor
import requests

class Uploader:
    def __init__(self, max_workers=4):
        self.executor = ThreadPoolExecutor(max_workers=max_workers)

    def upload_chunk(self, chunk_path):
        """注意添加重试逻辑和凭证刷新"""
        try:
            with open(chunk_path, 'rb') as f:
                # 实际替换为 Autodl 的 API 端点
                resp = requests.post('https://upload.autodl.com/api/v1/upload',
                                    files={'file': f},
                                    headers={'Authorization': 'Bearer xxx'})
                return resp.json()
        except Exception as e:
            print(f"上传失败 {chunk_path}: {str(e)}")
            raise

    def batch_upload(self, chunk_files):
        futures = []
        for cf in chunk_files:
            futures.append(self.executor.submit(self.upload_chunk, cf))

        # 等待所有任务完成
        for f in futures:
            f.result()

避坑指南

内存优化技巧

  • 使用生成器逐块读取文件:
    def read_in_chunks(file_object, chunk_size=1024*1024):
        while True:
            data = file_object.read(chunk_size)
            if not data:
                break
            yield data

错误重试策略

from time import sleep

def exponential_backoff(retries, max_wait=60):
    wait_time = min(2 ** retries, max_wait)
    sleep(wait_time + random.uniform(0, 1))  # 添加随机抖动 

性能验证

测试环境:Autodl V100 实例 + 500Mbps 带宽

分片大小 上传耗时 吞吐量
200MB 82min 40MB/s
500MB 68min 48MB/s
1GB 75min 44MB/s

延伸思考

  1. 如何适配 S3 协议的上传接口?
  2. 当数据集包含数百万小文件时,分片策略需要如何调整?
  3. 怎样利用 GPU 加速压缩过程?(提示:查看 NVIDIA 的 nvcomp 库)

实际部署时,建议先用小数据集测试分片大小和线程数的组合效果。我们最终方案将 200GB 数据集的上传时间从 6 小时压缩到 2.5 小时,网络利用率提升到 85% 以上。

正文完
 0
评论(没有评论)