现象
--multirun 配上非空的 exp.seed 时,实验一启动就崩:
File "abses/core/experiment.py", line 390, in _get_seed
r = random.Random(self._base_seed + job_id * 1000 + run_id)
TypeError: unsupported operand type(s) for +: 'int' and 'str'
原因
Experiment.job_id(abses/core/experiment.py:299-306)在 Hydra 环境下返回:
return self.hydra_config.job.get("id", 0)
而 Hydra 把 hydra.job.id 声明成字符串(hydra/conf/__init__.py):
id: str = MISSING # 第 61 行
num: int = MISSING # 第 64 行 ← 同一个数字,但类型是 int
BasicLauncher 赋值时写的是整数(sweep_config.hydra.job.id = idx),但 OmegaConf 按 schema 强制转成了 str。于是 job_id * 1000 变成一个重复 1000 次的字符串,int + str 抛 TypeError。
归档产物可以佐证:任意一次 multirun 的 .hydra/hydra.yaml 里都是 id: '2'(带引号)。
复现
python -m your_pkg --multirun some=a,b exp.repeats=2 # exp.seed 非 None
单次运行(hydra.run.dir)不受影响 —— 单次运行下 job.id 不参与这条路径。
为什么现在才暴露
_get_seed 开头有 if self._base_seed is None: return None。只要没设种子就永远走不到那行加法。我们之前的实验一直没设 exp.seed(也因此不可复现),最近为了可复现加上种子,"multirun + 有种子"这个组合第一次相遇就炸。
建议修法
用 hydra.job.num(schema 本就是 int)而不是 hydra.job.id:
return self.hydra_config.job.get("num", 0)
或者保守一点,就地转换:
return int(self.hydra_config.job.get("id", 0))
注意 job.id 在某些 launcher(如 submitit)下会是形如 "12345_0" 的作业号,int() 会失败 —— 所以 job.num 更稳妥。
环境
- abses 0.11.7(本地 HEAD
c570cac7 同样存在,行号一致)
- hydra-core 1.3.5,Python 3.11
下游临时兜底
我们在自己的入口里用子类覆盖 job_id 强制转 int(我们把 abses 钉死在 0.11.7,理由是可复现性,暂不动版本)。上游修好后这个子类可以纯减法删掉。
另见姊妹 issue:_is_hydra_parallel 导致 num_process 完全失效。
现象
--multirun配上非空的exp.seed时,实验一启动就崩:原因
Experiment.job_id(abses/core/experiment.py:299-306)在 Hydra 环境下返回:而 Hydra 把
hydra.job.id声明成字符串(hydra/conf/__init__.py):BasicLauncher赋值时写的是整数(sweep_config.hydra.job.id = idx),但 OmegaConf 按 schema 强制转成了str。于是job_id * 1000变成一个重复 1000 次的字符串,int + str抛 TypeError。归档产物可以佐证:任意一次 multirun 的
.hydra/hydra.yaml里都是id: '2'(带引号)。复现
python -m your_pkg --multirun some=a,b exp.repeats=2 # exp.seed 非 None单次运行(
hydra.run.dir)不受影响 —— 单次运行下job.id不参与这条路径。为什么现在才暴露
_get_seed开头有if self._base_seed is None: return None。只要没设种子就永远走不到那行加法。我们之前的实验一直没设exp.seed(也因此不可复现),最近为了可复现加上种子,"multirun + 有种子"这个组合第一次相遇就炸。建议修法
用
hydra.job.num(schema 本就是int)而不是hydra.job.id:或者保守一点,就地转换:
注意
job.id在某些 launcher(如 submitit)下会是形如"12345_0"的作业号,int()会失败 —— 所以job.num更稳妥。环境
c570cac7同样存在,行号一致)下游临时兜底
我们在自己的入口里用子类覆盖
job_id强制转 int(我们把 abses 钉死在 0.11.7,理由是可复现性,暂不动版本)。上游修好后这个子类可以纯减法删掉。另见姊妹 issue:
_is_hydra_parallel导致num_process完全失效。