Skip to main content
你有一堆按类别分好目录的图片,想训一个模型判断「这张属于哪一类」。三条命令:
原生 PyTorch 2.14.0,独立运行时。它是平台上唯一属于 supervised 类别的方法: 带标注的输入/目标对、从初始化开始训练,spec 里没有任何 base model。 可运行的完整例子在示例项目 tuneplane-examplesexperiments/pytorch-imgcls_simple-cnn_digit-images_v1

数据长什么样

目录名就是类名。 没有标注文件,没有 CSV:
这就是 torchvision.datasets.ImageFolder 的约定。类别数写进 config.yamlnum_classes代码一行都不用改 val/ 是必须的,而且要和 train/ 没有重叠 —— 平台报的准确率是在这批图上算的, 掺了训练图这个数就没有意义了。

创建

得到 train.pyconfig.yaml,两个都归你。train.py 里只有 build_modelbuild_datasets 是留给你改的;其余部分是平台契约 —— 参数怎么传进来、只在 rank 0 上报、 产物写在哪。

配置

config.yaml 是平铺的,没有继承。每个键都由 recipe 声明,所以拼错、越界在 tp validate 就报,不必等排到 GPU:
--set 覆盖同样这些键,走同一份声明校验:
全部可调参数与取值范围:tp methods pytorch/image-classification
arch 用 torchvision 架构(resnet18 等)时输入必须是三通道。单通道灰度图会被 明确拒绝并告诉你怎么改,而不是在第一个卷积上抛一个只提张量形状的错误。

数据从哪来

图片语料是一个目录,所以和文本框架不同,这个方法拿到的是挂载点而不是文件。两条路: 平台数据集 —— 不可变、带版本,训练时从共享缓存读、不出网:
Volume —— 就地维护的目录,没有版本,只读挂载:
怎么选:会变的、一直在加的原始素材走 Volume;要复现、要说清「训的是哪一版」的走数据集。 详见数据集与 Volume 两个都不声明时:input_pipeline: imagefolder 会去读工作目录下的 data/{train,val}(本地调试用), 而 mnist / cifar10 会尝试联网下载 —— 笔记本上没问题,集群节点通常没有出网路由。正式跑请声明其中一条。

拉起

adapter 按服务端计费的拓扑编译出 torchrun。单卡就够用;多卡时 batch_size 是每进程的。 两台及以上会编译成带 rendezvous 的进程组,每台机器一个 launcher 进程 —— 实验里不需要读卡数, train.py 启动时 RANK / LOCAL_RANK / WORLD_SIZE 已经就位。
多机需要 kuberay 或 slurm 后端,和这里其它走进程组的框架一样。

训练之后

  • 控制台曲线:train/lossvalidation/lossvalidation/accuracytrain/lr
  • checkpoints/best.pt,以及每次评估的 epoch 快照
  • 准确率是在 val/ 上算的 预测对的张数 / 总张数
这个方法没有 tp export / tp eval,这是明确声明不是遗漏:分类器没有任何一种 HuggingFace 导出是有意义的,平台也没有给它打分的基准 harness。tp submit --then export 会在编译期被拒。

换成你自己的模型

train.py 的两个函数就行:
其余部分不要动 —— 那是让控制台画得出曲线、产物登记找得到权重的原因。

为什么不是 custom/custom

shell 脚本也能调 torchrun,差别在这四点: 训练器确实不是这个形状时才用 custom

镜像(运维一次性)

pytorch-2.14.0 由部署侧构建,catalog 不内嵌地址:
然后在控制台填:设置 → 运行时 → 镜像 → 「PyTorch 默认镜像」,给个 tag 即可,保存立即生效。 TUNEPLANE_IMAGE_PYTORCH 是同一项的环境变量形态,作为控制台值的基线。没配的话提交会明确报 runtime_id='pytorch-2.14.0' has no built-in OCI source