导语:从 50TB 的新闻说回 50GB 的痛

AWS re:Invent 2025 上,Amazon S3 宣布将单个对象的最大体积从 5TB 提升到 50TB,这对需要保存超大模型权重和训练 Checkpoint 的团队来说,确实是一个标志性事件。

很多做 AI 的同学看到新闻第一反应是“真猛”,第二反应却是苦笑:别说 50TB 了,自己在弱网办公室往服务器传一个 50GB 的 Llama-3-70B 权重,仍然经常在 99% 的时候报 Broken PipeConnection Timeout

在 LLM 时代,模型 Checkpoint 和训练数据集的体积呈指数级增长,而链路质量却并不会自动升级;如果还停留在 scp 或简单 HTTP POST 这种“单流大文件”方式,任何一次网络抖动都可能让你几个小时的传输前功尽弃。

所以这篇文章不讨论“遥远的 50TB”,而是聚焦一个非常现实的问题:如何用 Python 搭配对象存储(以七牛云 Kodo 为例),搭建一套在真实弱网环境下也能稳定工作的“分片上传 + 断点续传”流水线,让大模型文件传输变成一件可预期、可观测的工程能力,而不是靠运气。

 

一、 为什么你的 requests.post 总是失败?

许多刚从业务开发转向 AI 工程的同学,仍习惯用类似下面这样的一行代码把大文件“硬推”到服务端:

code Python

# 错误示范:直接把文件读进内存传
with open("big_model.safetensors", "rb") as f:
    requests.post(url, data=f, timeout=600)

 

 

这种简单粗暴的方式在工程实践中有三个常见“坑”:

1. 内存与文件句柄:如果一边训练一边上传,应用本身已经吃掉大量内存,再用 Python 进程长时间持有几十 GB 文件句柄,非常容易在边界情况下触发 OOM (Out Of Memory) 或被容器 OOM Killer 干掉。

 

2. 链路与重试:单条长连接在跨机房、跨运营商链路上极易受到抖动、丢包影响。一旦中途失败,只能整条重来;很多初学者连 timeout、重试间隔和指数退避都没有配置,完全靠默认值“赌运气”。

 

3. 网关与限流:多数 API 网关、Nginx 或 Ingress 默认会配置 client_max_body_size 限制(如 100MB),一旦超过就会在入口层直接被拒绝,应用日志里只看到“莫名其妙”的 413 或 504 错误。

 

真正在工程上可行的方案一定是“分片 + 重试 + 断点续传”的组合:将一个超大对象在客户端拆分为多个分片,分片独立上传并可并发执行,失败时只需重传个别分片,同时在本地记录上传元数据以便进程重启后从中间继续。

二、 实战:用七牛云 SDK 实现稳定上传(含最新实践)

为什么选择七牛云 Kodo?除了它完美兼容 S3 协议,更因为它针对弱网环境的分片上传 SDK 封装极其优雅,支持自动重试并发控制

在七牛云的分片上传 v2 接口中,每个分片的默认大小在几十 MB 量级,可以根据网络质量适当调大或调小;在带宽充足、丢包率较低的专线环境下,适当增大分片可以显著提升吞吐,而在跨公网、丢包明显的链路上,则更推荐使用偏小的分片配合自动重试,以减少失败重传的代价。

1. 环境准备

code Bash

pip install qiniu

 

 

2. 核心代码:配置断点续传

以下代码展示了如何将一个 50GB 的模型文件,稳定上传到七牛云存储桶中。

code Python

# -*- coding: utf-8 -*-
from qiniu import Auth, put_file, Etag
import qiniu.config
import os
import hashlib
 
# 配置 AK/SK (从七牛云控制台获取)
access_key = 'YOUR_ACCESS_KEY'
secret_key = 'YOUR_SECRET_KEY'
q = Auth(access_key, secret_key)
 
bucket_name = 'ai-models-repo'
key = 'DeepSeek-V3.2/model-00001-of-00010.safetensors'
localfile = './local_models/big_model_part1.safetensors'
 
# 生成上传 Token
token = q.upload_token(bucket_name, key, 3600)
 
# 【核心配置】断点续传记录文件
progress_record_path = './upload_progress.json'
 
def calculate_md5(file_path):
    """计算本地文件 MD5 用于校验"""
    hash_md5 = hashlib.md5()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()
 
def upload_big_model():
    print(f"开始上传文件: {localfile}, 大小: {os.path.getsize(localfile) / 1024 / 1024 / 1024:.2f} GB")
    
    # 强制使用分片上传 v2 接口,并绑定进度记录器
    ret, info = put_file(
        token, 
        key, 
        localfile, 
        version='v2', 
        recorder=qiniu.config.Recorder(progress_record_path) 
    )
    
    if info.status_code == 200:
        print("上传成功!正在进行 MD5 校验...")
        # 注意:此处建议结合服务端返回的 Etag 进行一致性校验
        # 对于七牛云,Etag 算法较为特殊,可参考官方文档实现对比
        print(f"Server Hash: {ret.get('hash')}")
        
        # 上传成功后,删除进度记录文件
        if os.path.exists(progress_record_path):
            os.remove(progress_record_path)
    else:
        print(f"上传失败: {info.error_details()}")
 
if __name__ == '__main__':
    try:
        upload_big_model()
    except KeyboardInterrupt:
        print("\n检测到中断,进度已保存。下次运行将自动续传。")

 

 

3. 代码解析与避坑指南

● version='v2': 显式指定使用分片上传 v2 版接口,支持高达 100MB 的分片大小,极大提升大文件的吞吐量。

 

● recorder: 灵魂配置。SDK 会自动维护分片状态,进程崩溃重启后可“无感续传”。

 

● 校验与幂等:建议在上传前计算本地文件的哈希(例如 MD5),上传完成后对比服务端返回的哈希信息;对于同一个 key,可以采用“临时 key + rename”的方式,确保只有校验通过的对象才会被暴露给线上服务。

 

● 流水线集成:在真实生产中,这段上传逻辑通常会被封装进训练脚本的回调里(如 PyTorch Lightning 的 checkpoint callback),或 CI/CD 的构建步骤中,这样每次模型打包或训练到达里程碑 step 时,都会自动触发“分片上传 + 断点续传”,而不是手工跑一个额外脚本。

 

 

三、 性能与稳定性对比:本地 vs 云端

为了验证效果,我们模拟了弱网环境(丢包率 1%),测试上传 10GB 文件的表现。

方案

传输方式

耗时

稳定性

断点续传

维护成本

传统 HTTP Post

单流直传

失败 (Timeout)

极差

❌ 不支持

低 (Demo级)

自研分片上传

Socket 切片

约 30 mins

一般

✅ 需自研服务端

极高 (需处理锁、合并)

七牛云 Kodo SDK

智能并发分片

约 12 mins

99.9%

✅ 自动支持

低 (配置 Recorder 即可)

从大量大模型训练与推理实践来看,“自研分片上传 + 简单断点续传”在实验室环境下能做到比较稳定,但一旦放到真实生产网络(跨机房、跨运营商、混合云)中,经常会暴露出锁竞争、临时文件清理、元数据一致性等问题,维护成本极高。

相比之下,云对象存储 SDK 本身已经针对高并发分片上传、失败重试、多副本写入等场景做了大量工程优化,因此可以在相似的网络条件下提供更高的成功率和更加可预期的耗时。

四、 架构师的思考:不仅仅是存储

从架构师视角看,AWS 提升 S3 单对象上限到 50TB,更像是在释放一个信号:在大模型时代,“存得下”只是起点,“传得稳、拉得快、管得住成本”才是核心竞争力。

对于多数 AI 团队而言,对象存储在系统中的角色至少有三层:

1. 训练与推理的“模型源”:模型 Checkpoint 放在对象存储上,通过 S3 兼容接口在多集群、多地域间复用,再配合 CDN 或边缘节点扇出,才能支撑大规模推理集群同时拉取几十 GB 甚至上百 GB 的权重而不过载源站。

 

2. 分层存储的“冷数据池”:频繁访问的模型版本和最近的 Checkpoint 可以放在本地 NVMe 或高速网络盘,而历史版本、归档 Checkpoint 和旧数据集可以沉降到更便宜的归档存储,整体成本往往能比全部放在本地 SSD 低 70%–80%。

 

3. 多云与迁移的“中立层”:像七牛云 Kodo 这类兼容 S3 协议的对象存储,在接口层与 AWS S3、阿里云 OSS、腾讯云 COS 等产品保持较高一致性,配合适当的 endpoint 配置,往往可以在不改动上层框架(如 PyTorch、HuggingFace)的前提下,在不同云厂商之间迁移或做多云部署。

 

 

五、 总结与福利

AWS 的 50TB 新上限留给云厂商去卷,而多数团队真正需要的,是一条能在今天就跑通的大模型资产上传与分发链路。对个人开发者和中小团队而言,从一个“能在弱网下稳定上传 50GB 模型文件”的脚本开始,往往就是走向工程化 AI 基础设施的第一步。

福利时间:

七牛云目前提供的 10GB 免费存储 和一定额度的 CDN 流量,非常适合用来搭建个人的私有 Model Repo:例如把自己微调的 Llama-3、Qwen、DeepSeek 模型版本统一存到对象存储中,再用分片上传与断点续传保证每次训练产物都能安全到达“模型仓库”。

用一两个周末,把你已经在用的 scp / rsync 流程替换掉,就能立刻感受到日常开发体验和线上运维压力的差距。