{"record":{"id":"b1b94b9b50a5dc88","repo":"facebookresearch/detectron2","slug":"bias-lr-factor-requires-base-lr","errorCode":null,"errorMessage":"bias_lr_factor requires base_lr","messagePattern":"bias_lr_factor requires base_lr","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"detectron2/solver/build.py","lineNumber":192,"sourceCode":"\n    Example:\n    ::\n        torch.optim.SGD(get_default_optimizer_params(model, weight_decay_norm=0),\n                       lr=0.01, weight_decay=1e-4, momentum=0.9)\n    \"\"\"\n    if overrides is None:\n        overrides = {}\n    defaults = {}\n    if base_lr is not None:\n        defaults[\"lr\"] = base_lr\n    if weight_decay is not None:\n        defaults[\"weight_decay\"] = weight_decay\n    bias_overrides = {}\n    if bias_lr_factor is not None and bias_lr_factor != 1.0:\n        # NOTE: unlike Detectron v1, we now by default make bias hyperparameters\n        # exactly the same as regular weights.\n        if base_lr is None:\n            raise ValueError(\"bias_lr_factor requires base_lr\")\n        bias_overrides[\"lr\"] = base_lr * bias_lr_factor\n    if weight_decay_bias is not None:\n        bias_overrides[\"weight_decay\"] = weight_decay_bias\n    if len(bias_overrides):\n        if \"bias\" in overrides:\n            raise ValueError(\"Conflicting overrides for 'bias'\")\n        overrides[\"bias\"] = bias_overrides\n    if lr_factor_func is not None:\n        if base_lr is None:\n            raise ValueError(\"lr_factor_func requires base_lr\")\n    norm_module_types = (\n        torch.nn.BatchNorm1d,\n        torch.nn.BatchNorm2d,\n        torch.nn.BatchNorm3d,\n        torch.nn.SyncBatchNorm,\n        # NaiveSyncBatchNorm inherits from BatchNorm2d\n        torch.nn.GroupNorm,\n        torch.nn.InstanceNorm1d,","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/facebookresearch/detectron2/blob/a2f4a8771ab77e8411c26b27f24f9489a28a2453/detectron2/solver/build.py#L174-L210","documentation":"get_default_optimizer_params needs a scalar base learning rate to compute per-bias-parameter LR overrides. If bias_lr_factor is set but base_lr is None (weight_decay path where LR comes from overrides), there is no LR to multiply.","triggerScenarios":"Calling build_optimizer/get_default_optimizer_params with bias_lr_factor != 1.0 and base_lr=None, e.g. when SOLVER.BASE_LR is unset while a custom optimizer passes weight_decay params only.","commonSituations":"Custom optimizer builders that pass weight_decay but not base_lr; configs that rely on per-module lr overrides while also setting bias_lr_factor.","solutions":["Pass base_lr (e.g. cfg.SOLVER.BASE_LR) to get_default_optimizer_params/build_optimizer","Drop bias_lr_factor (set to None or 1.0) so no bias LR scaling is requested","Supply the bias LR directly via overrides={'bias': {'lr': ...}} instead"],"exampleFix":"# before\nparams = get_default_optimizer_params(model, bias_lr_factor=2.0, weight_decay=1e-4)\n# after\nparams = get_default_optimizer_params(model, base_lr=cfg.SOLVER.BASE_LR, bias_lr_factor=2.0, weight_decay=1e-4)","handlingStrategy":"validation","validationCode":"if bias_lr_factor is not None and bias_lr_factor != 1.0:\n    assert base_lr is not None, 'bias_lr_factor requires base_lr (set cfg.SOLVER.BASE_LR)'","typeGuard":null,"tryCatchPattern":"try:\n    params = get_default_optimizer_params(model, base_lr=None, bias_lr_factor=f)\nexcept ValueError as e:\n    raise ValueError(f'optimizer build failed: {e}; pass base_lr') from e","preventionTips":["Always pass cfg.SOLVER.BASE_LR to optimizer builders","Set SOLVER.BASE_LR in config even when using custom optimizers"],"tags":["detectron2","optimizer","solver","config"],"backgroundTag":"missing-required-parameter","analyzedSha":"a2f4a8771ab77e8411c26b27f24f9489a28a2453","analyzedAt":"2026-08-27T12:08:21.260Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}