patch_barrier_timeout.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #!/usr/bin/env python3
  2. """Make SGLang's post-load monitored_barrier timeout configurable.
  3. The launcher boots this lane with a per-node load time that varies wildly
  4. (warm NFS cache ~40 min, cold up to 3.5 h on GB10 UMA where page-cache
  5. pressure slows the tail ranks). The stock post-load barrier is 480 s — a
  6. slow-but-fine rank gets murdered right after rank 0 finishes
  7. ("Rank N failed to pass monitoredBarrier in 480000 ms").
  8. Patch (idempotent, anchor-based — refuses to touch a file whose anchor does
  9. not match):
  10. UNBALANCED_MODEL_LOADING_TIMEOUT_S = 480
  11. →
  12. UNBALANCED_MODEL_LOADING_TIMEOUT_S = int(
  13. os.environ.get("SGLANG_UNBALANCED_LOAD_TIMEOUT_S", "480")
  14. )
  15. `os` is already imported at module top. Runtime knob:
  16. SGLANG_UNBALANCED_LOAD_TIMEOUT_S=<seconds> (recipe [env]).
  17. """
  18. import hashlib
  19. import re
  20. import sys
  21. from pathlib import Path
  22. ANCHOR = re.compile(
  23. r"^UNBALANCED_MODEL_LOADING_TIMEOUT_S = 480"
  24. r"( # leave more time for post data processing)?$",
  25. re.M,
  26. )
  27. NEW = (
  28. "UNBALANCED_MODEL_LOADING_TIMEOUT_S = int("
  29. "\n os.environ.get(\"SGLANG_UNBALANCED_LOAD_TIMEOUT_S\", \"480\")"
  30. ") # leave more time for post data processing; launcher-tunable"
  31. )
  32. TARGET = Path(
  33. "/sgl-workspace/sglang/python/sglang/srt/model_executor"
  34. "/model_runner_components/load_model_utils.py"
  35. )
  36. def main() -> None:
  37. args = sys.argv[1:]
  38. check = "--check" in args
  39. src = TARGET.read_text()
  40. matches = ANCHOR.findall(src)
  41. patched = NEW in src
  42. if patched:
  43. print(f"already patched: {TARGET}")
  44. sys.exit(0 if check else 0)
  45. if len(matches) != 1:
  46. sys.exit(
  47. f"refusing: anchor matched {len(matches)} times in {TARGET} "
  48. "(upstream changed; the patch must be re-anchored)"
  49. )
  50. if check:
  51. print(f"anchor present, not applied: {TARGET}")
  52. return
  53. out = ANCHOR.sub(lambda m: NEW, src, count=1)
  54. before = hashlib.md5(src.encode()).hexdigest()
  55. TARGET.write_text(out)
  56. after_hash = hashlib.md5(TARGET.read_text().encode()).hexdigest()
  57. print(f"patched {TARGET} (md5 {before} -> {after_hash})")
  58. if __name__ == "__main__":
  59. main()