课程首页· 术语表· 第 4 课 / 共 5 课

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.pyWorldModel(RSSM+头)+ ImagBehavior(想象 Actor-Critic)第 2、3 课
networks.pyRSSM 类、编码/解码 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] 那张超参表看着密,但有了前三课,你能逐行读懂。挑最关键的几行:

方案超参表节选(§2.1.5)——现在你能看懂"为什么"
超参默认HVAC对应哪课 / 为什么这么填
imag_horizon1520 第 3 课:想象前推步数。HVAC 热惯性大,延长前瞻
discount0.9970.99 第 3 课:未来奖励折扣。能耗即时性强,更看近期
batch_length6464 第 2 课:每次抽多长的历史序列训世界模型(~16h 窗口)
dyn_deter / dyn_stoch512 / 32不变 第 2 课:潜在状态的维度(确定性 512 + 随机性 32)。V3 的"固定超参"就是这些
steps1e65e5 总训练步数。HVAC 仿真慢,5e5 够收敛(省时间)
action_repeat21 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/百分比再发给冷机。

参考来源 NM512/dreamerv3-torch(README 命令范例 + 代码结构) · 方案文档 §2.1.4(hvac.py 骨架)/ §2.1.5(超参表)/ §8.2(风险 T1) · 姊妹课:Sinergym 怎么把 EnergyPlus 包成 Gymnasium