{
  "id": "pytorch/torch-compile-graph-break",
  "signature": "RuntimeError: torch.compile: function 'forward' failed with a graph break. Falling back to eager mode. Consider rewriting the function to avoid dynamic control flow.",
  "signature_zh": "RuntimeError: torch.compile：函数 'forward' 发生图断裂，回退到 eager 模式。请考虑重写函数以避免动态控制流。",
  "regex": "torch\\.compile.*failed with a graph break",
  "domain": "pytorch",
  "category": "runtime_error",
  "subcategory": null,
  "root_cause": "torch.compile encountered a graph break (e.g., dynamic control flow, unsupported operations, or Python-side side effects) that prevents the entire computation graph from being captured, forcing a fallback to eager mode and potentially reducing performance.",
  "root_cause_type": "generic",
  "root_cause_zh": "torch.compile 遇到图断裂（例如动态控制流、不支持的操作或 Python 端副作用），导致无法捕获整个计算图，被迫回退到 eager 模式，并可能降低性能。",
  "versions": [
    {
      "version": "torch>=2.1",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "torch>=2.3",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "Python 3.11",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Disabling torch.compile entirely with torch.compiler.reset()",
      "why_fails": "This removes the performance benefits of compilation and does not address the underlying code pattern that causes graph breaks.",
      "fail_rate": 0.95,
      "condition": "",
      "sources": []
    },
    {
      "action": "Adding @torch.jit.script decorator on top of torch.compile",
      "why_fails": "torch.jit.script and torch.compile are different systems; mixing them can cause conflicts and unexpected behavior, not fixing the graph break.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    },
    {
      "action": "Using torch.inference_mode() to disable autograd entirely",
      "why_fails": "While inference mode reduces overhead, it does not resolve graph breaks caused by dynamic control flow in the model's forward method.",
      "fail_rate": 0.85,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Refactor the forward method to remove dynamic control flow. Replace if statements with torch.where or masked operations:\n\n# Before (causes graph break):\nif x.sum() > 0:\n    y = x * 2\nelse:\n    y = x + 1\n\n# After (no graph break):\nmask = (x.sum() > 0).float()\ny = mask * (x * 2) + (1 - mask) * (x + 1)",
      "success_rate": 0.85,
      "how": "Refactor the forward method to remove dynamic control flow. Replace if statements with torch.where or masked operations:\n\n# Before (causes graph break):\nif x.sum() > 0:\n    y = x * 2\nelse:\n    y = x + 1\n\n# After (no graph break):\nmask = (x.sum() > 0).float()\ny = mask * (x * 2) + (1 - mask) * (x + 1)",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use torch.compiler.disable() decorator on specific submodules that cause graph breaks, while keeping the rest compiled:\n\n@torch.compiler.disable\ndef custom_op(x):\n    return my_python_function(x)\n\nmodel = torch.compile(model)",
      "success_rate": 0.8,
      "how": "Use torch.compiler.disable() decorator on specific submodules that cause graph breaks, while keeping the rest compiled:\n\n@torch.compiler.disable\ndef custom_op(x):\n    return my_python_function(x)\n\nmodel = torch.compile(model)",
      "condition": "",
      "sources": []
    },
    {
      "action": "Enable torch._dynamo.config.verbose=True and torch._dynamo.config.suppress_errors=True to get detailed logs on where the graph break occurs:\n\nimport torch._dynamo\ntorch._dynamo.config.verbose = True\ntorch._dynamo.config.suppress_errors = True",
      "success_rate": 0.75,
      "how": "Enable torch._dynamo.config.verbose=True and torch._dynamo.config.suppress_errors=True to get detailed logs on where the graph break occurs:\n\nimport torch._dynamo\ntorch._dynamo.config.verbose = True\ntorch._dynamo.config.suppress_errors = True",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "Refactor the forward method to remove dynamic control flow. Replace if statements with torch.where or masked operations:\n\n# Before (causes graph break):\nif x.sum() > 0:\n    y = x * 2\nelse:\n    y = x + 1\n\n# After (no graph break):\nmask = (x.sum() > 0).float()\ny = mask * (x * 2) + (1 - mask) * (x + 1)",
    "Use torch.compiler.disable() decorator on specific submodules that cause graph breaks, while keeping the rest compiled:\n\n@torch.compiler.disable\ndef custom_op(x):\n    return my_python_function(x)\n\nmodel = torch.compile(model)",
    "Enable torch._dynamo.config.verbose=True and torch._dynamo.config.suppress_errors=True to get detailed logs on where the graph break occurs:\n\nimport torch._dynamo\ntorch._dynamo.config.verbose = True\ntorch._dynamo.config.suppress_errors = True"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://pytorch.org/docs/stable/torch.compiler.html#debugging-graph-breaks",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.84,
  "fix_success_rate": 0.7,
  "resolvable": "true",
  "first_seen": "2024-01-15",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}