Lesson 04 · 跑起来
一行命令跑起来:configs / HvacEnv / 训练循环
前三课讲原理。这一课把原理落到代码——方案 §2.1.4 的环境骨架、§2.1.5 的超参表、怎么一行命令开训。
前三课你理解了 DreamerV3 的"精神"。这一课是"动手"——它把第 3 课那张三步循环图,对应到真实代码文件上:你要写哪个文件、跑哪条命令、超参表怎么读。讲完后,方案 §2.1(技术选型)对你就不再有黑盒。本课围绕方案选的 NM512/dreamerv3-torch(commit 6ef8646)讲——仓库现状的坑留到第 5 课统一讲。
先看代码地图:四个文件各干嘛
方案 [§2.1.4] 列了 DreamerV3-torch 的代码结构。前三课讲的每个概念,都能在这张图里找到落点:
| 文件 | 内容 | 对应概念 |
|---|---|---|
dreamer.py | 训练循环 + 策略推理 | 第 3 课的"三步循环"在这 |
models.py | WorldModel(RSSM+头)+ ImagBehavior(想象 Actor-Critic) | 第 2、3 课 |
networks.py | RSSM 类、编码/解码 MLP | 第 2 课的四个零件 |
envs/ | 环境定义(dmc/atari/crafter/minecraft…) | 我们要在这里加 hvac.py |
configs.yaml | 所有超参 | 方案 §2.1.5 那张表 |
所以接 HVAC 的侵入面很小:主要就是在 envs/ 下新增一个 hvac.py,其余文件几乎不用动。这正是方案 [§2.1.1] 选 PyTorch 版而非官方 JAX 版的理由之一("修改 HVAC 自定义环境的侵入面小")。
唯一要写的代码:envs/hvac.py
方案 [§2.1.4] 给了骨架。我们逐段看懂它——它实现的是标准 Gymnasium(原 OpenAI Gym,RL 环境的通用接口)接口:
class HvacEnv(gym.Env): # 观测空间 = 楼的状态向量;动作空间 = 控制量向量 def __init__(self, idf_path, weather_path, config): self.observation_space = gym.spaces.Dict({ 'vector': gym.spaces.Box(...) # 室温/水温/CO₂/室外温...(第2课的观测 o_t) }) self.action_space = gym.spaces.Box(...) # 冷机功率/水泵频率/AHU风量...(动作 a_t) self.simulator = EnergyPlusSimulator(...) # 背后接 Sinergym→EnergyPlus(见姊妹课) def reset(self, seed=None): obs = self.simulator.reset() # 一轮新仿真开始 return {'vector': obs}, {} def step(self, action): real_action = self._denormalize(action) # [-1,1] → 真实控制值 obs, reward, terminated, truncated, info = self.simulator.step(real_action) return {'vector': obs}, reward, terminated, truncated, info
一行命令开训
DreamerV3-torch 是"配置驱动"的——所有超参在 configs.yaml,命令行只指定用哪组配置、跑哪个任务:
$ python3 dreamer.py \ --configs hvac \ # 用我们为 HVAC 写的那组配置 --task hvac_summer \ # 任务名(对应 envs/hvac.py 里注册的环境) --logdir ./logdir/hvac_summer # 日志/checkpoint 存哪
(命令格式参照 dreamerv3-torch README 的范例:python3 dreamer.py --configs dmc_vision --task dmc_walker_walk --logdir ...,换成 HVAC 的 task 名即可。)训完会在 logdir/ 下产 checkpoint,第 5 课的推理服务就是加载它。
读方案超参表:每个数在控什么
方案 [§2.1.5] 那张超参表看着密,但有了前三课,你能逐行读懂。挑最关键的几行:
| 超参 | 默认 | HVAC | 对应哪课 / 为什么这么填 |
|---|---|---|---|
imag_horizon | 15 | 20 | 第 3 课:想象前推步数。HVAC 热惯性大,延长前瞻 |
discount | 0.997 | 0.99 | 第 3 课:未来奖励折扣。能耗即时性强,更看近期 |
batch_length | 64 | 64 | 第 2 课:每次抽多长的历史序列训世界模型(~16h 窗口) |
dyn_deter / dyn_stoch | 512 / 32 | 不变 | 第 2 课:潜在状态的维度(确定性 512 + 随机性 32)。V3 的"固定超参"就是这些 |
steps | 1e6 | 5e5 | 总训练步数。HVAC 仿真慢,5e5 够收敛(省时间) |
action_repeat | 2 | 1 | HVAC 控制已含时间粒度(15min/步),不需重复动作 |
一个判断准则:和"物理时间尺度"耦合的参数(horizon / discount / steps / time_limit)要按 HVAC 改;和"网络结构"耦合的(dyn_* / hidden / lr)保持默认——后者正是 V3"固定超参"的覆盖范围。
接 HVAC 的代码侵入面很小:主要新增 envs/hvac.py(实现 Gymnasium 的 reset/step,观测=楼状态、动作=控制量、背后接 Sinergym→EnergyPlus)。训练是一行配置驱动的命令:python3 dreamer.py --configs hvac --task hvac_summer。读超参表的准则:物理时间尺度类参数(horizon/discount/steps)按 HVAC 调,网络结构类参数保持默认。
我们要新增的 envs/hvac.py,主要实现的是?
卡住了就问我:"动作为什么要 [-1,1] 再反归一化"如果让你困惑,可以问我——这是 RL 的通用约定(让算法和具体物理量纲解耦),我会解释 DreamerV3 内部只认归一化动作,_denormalize 把它翻译回真实 Hz/百分比再发给冷机。