# Tuning Deep Learning With Optuna

> Use when a deep-learning project needs Optuna hyperparameter search, a defensible search space, resource-aware GPU trial scheduling, resumable studies, pruning, or reproducible experiment reporting.

- Skill: `zhanggong0564/tuning-deep-learning-with-optuna` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add zhanggong0564/tuning-deep-learning-with-optuna`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zhanggong0564/tuning-deep-learning-with-optuna/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: zhanggong0564 (https://skillmd.com/u/zhanggong0564)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/zhanggong0564/tuning-deep-learning-with-optuna

---


# 使用 Optuna 调优深度学习

## 核心原则

先证明训练与验证链路可信，再让 Optuna 搜索。只搜索项目真实支持的参数；验证集决定 Trial，测试集只用于最终评估。

## 工作流

### 1. 审计项目

只读检查训练入口、配置覆盖方式、验证循环、checkpoint、数据划分、依赖和输出目录。记录代码与数据版本、Python/框架/CUDA/Optuna 版本，以及 GPU、CPU、内存、磁盘和现有训练进程。

确认：

- 参数能从命令行或配置安全覆盖；
- 每个 Trial 能写入独立目录；
- 目标验证指标可可靠提取，最好能按 epoch 上报；
- 训练集、验证集、测试集没有职责混用；
- 单 Trial 是单卡还是 DDP，batch size 是每卡值还是全局值。

发现训练不能启动、指标不可提取、数据划分泄漏或输出会覆盖时，停止并报告阻塞项。

### 2. 建立基线

优先复用代码版本、完整配置、指标和模型路径都可追溯的基线；否则先请求运行基线的许可。记录目标指标、最佳 epoch、耗时、峰值显存和最佳模型。

用基线约束搜索空间。不要根据参数名称套用通用范围；不要为用户未要求的参数擅自扩维。

### 3. 起草搜索方案

逐项列出当前值、类型、候选范围、采样方式、依据、依赖关系和风险。遵循：

| 参数 | 默认策略 |
|---|---|
| 学习率、权重衰减 | 跨数量级时用 `suggest_float(..., log=True)` |
| batch size、输入尺寸 | 只用经过资源与模型约束验证的离散值 |
| optimizer、scheduler | 只列代码真实支持的枚举值 |
| optimizer 专属参数 | 用条件搜索空间，不生成无效组合 |
| epoch | 通常作为预算，不做无界搜索 |

为搜索方案明确：目标指标与方向、Sampler seed、Pruner、全局 Trial 总预算、总 timeout、单 Trial epoch 上限、最大并发、存储、失败处理、停止方式和最优配置复验次数。

默认单目标使用 `TPESampler`。只有训练能按有意义的 step 上报可比指标时才使用 `MedianPruner`；否则关闭剪枝，不解析脆弱的控制台文本来伪造中间指标。

### 4. 请求批准

展示基线、搜索空间依据、预算、预计耗时、GPU 策略、存储、恢复语义和风险。必须取得明确批准，才可安装依赖、改训练代码或启动 Trial。

批准后保存不可变的方案快照，并计算包含目标、方向、搜索空间、预算、代码版本和数据版本的指纹。恢复时指纹不一致就拒绝混跑，创建新 run。

### 5. 接入训练流程

保留原训练入口兼容性，新增独立 Optuna 适配层。优先调用结构化训练函数；若只能启动子进程，让训练输出结构化 JSON/JSONL 指标，不依赖日志正则作为长期契约。

Objective 必须：

1. 从批准的空间采样并合并基线配置；
2. 创建唯一 Trial 目录并保存解析后配置；
3. 运行训练并上报验证指标；
4. 保存模型、指标、资源和状态；
5. 返回验证集目标指标；
6. 原样记录 OOM、NaN/Inf、退出码和异常。

将基线参数用 `study.enqueue_trial(..., skip_if_exists=True)` 放入同一 Study。并发 enqueue 仍可能重复，需由单一协调进程负责入队。

实现前读取 [实现与存储模式](references/implementation-patterns.md)。

### 6. 调度与恢复

GPU 训练默认每个 Worker 使用独立进程并绑定明确设备。安全并发数取 GPU、显存、CPU、内存、磁盘、现有负载和用户上限的最小值，并预留余量。

把 `n_trials` 定义为整个 Study 的全局完成预算，不是每个 Worker 的新增数量。每次领取 Trial 前重算剩余预算，避免多 Worker 或恢复后超额运行。

区分两种恢复：

- Study 恢复：保留 COMPLETE/PRUNED/FAIL，继续领取新 Trial；
- Trial 内恢复：仅在训练 checkpoint 同时保存模型、优化器、scheduler、epoch 和随机数状态时承诺。

资源不足或存储异常时停止领取新 Trial。不要把失败返回成虚假低分；不要在 OOM 后修改参数并继续记作同一 Trial。

### 7. 汇总与复验

只对 COMPLETE Trial 排名，单独汇总 PRUNED 和 FAIL。报告相对基线的指标、耗时、峰值显存、模型路径和失败率。完成 Trial 太少时，不强行解释参数重要性。

用独立目录和固定代码/数据版本重新训练最优参数。随机性明显时使用多个预先声明的种子，报告均值与波动。复验稳定后才在测试集做一次最终评估。

输出文件与状态契约见 [实验产物契约](references/artifact-contracts.md)。

## 停止条件

满足以下全部条件才宣布完成：

- 基线、搜索空间批准记录和 Study 均可追溯；
- 每个 Trial 有明确状态且没有输出覆盖；
- 全局预算、停止和恢复行为经过验证；
- 最优参数已独立复验；
- 报告区分搜索指标、复验指标和测试集最终指标；
- 原始代码、配置、模型和历史实验保持可恢复。

## 常见错误

| 错误 | 正确处理 |
|---|---|
| 两张 GPU 就默认并发 2 | 先确认单 Trial 单卡可容纳，DDP Trial 通常并发 1 |
| 多 Worker 各跑 `n_trials` | 使用全局预算，由协调层原子领取 |
| Journal 文件放 NFS 做多机并发 | 使用 PostgreSQL/MySQL；大规模节点考虑 gRPC proxy |
| “可恢复”含义含混 | 分别声明 Study 恢复和 Trial 内 checkpoint 恢复 |
| 所有 optimizer 共用盲目 lr 范围 | 用有依据的公共范围或条件空间 |
| 捕获异常后返回极差值 | 保留 FAIL 和真实异常，不污染完成 Trial |
| 搜索完成即发布最佳参数 | 独立复验后再最终测试 |

