sglang_tests.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SGLang serve command tests. Moved out of `docker/tests.rs` so the parent
  2. // module stays under the ≤500-line gate. Helpers (`tcls`, `make_dm_ctx`,
  3. // `squash`, ...) are in `super`.
  4. use super::*;
  5. fn sglang_recipe() -> Recipe {
  6. Recipe {
  7. build_profile: None,
  8. parent_model: None,
  9. archived: false,
  10. engine: "sglang".into(),
  11. name: "S".into(),
  12. docker_image: "sglang-img".into(),
  13. model: "org/sgl-model".into(),
  14. port: 8000,
  15. required_nodes: Some(4),
  16. pipeline_parallel_size: None,
  17. tensor_parallel_size: 4,
  18. args: RecipeArgs::List(vec!["--mem-fraction-static".into(), "0.8".into()]),
  19. env: HashMap::from([("TORCH_NCCL_ASYNC_ERROR_HANDLING".into(), "1".into())]),
  20. cluster: None,
  21. entrypoint: vec!["sglang".into(), "serve".into()],
  22. distributed_backend: Some(DistributedBackend::Mp),
  23. before_serve: vec![],
  24. after_stop: vec![],
  25. solo: None,
  26. deploy: DeployTarget::Docker,
  27. venv: None,
  28. venv_setup: VenvSetup::default(),
  29. venv_setup_script: None,
  30. mods: Default::default(),
  31. shm_size: String::new(),
  32. devices: vec![],
  33. memory_limit: None,
  34. cpus: None,
  35. sync_image: true,
  36. docker_image_dir: None,
  37. extra_mounts: vec![],
  38. extra_mounts_manifest: None,
  39. build: Default::default(),
  40. composed_model: None,
  41. staging: vec![],
  42. }
  43. }
  44. fn srun(recipe: &Recipe, node: &Node, head: bool) -> String {
  45. let tp = if recipe.required_nodes == Some(recipe.tensor_parallel_size) {
  46. 4
  47. } else {
  48. recipe.tensor_parallel_size
  49. };
  50. let mut ctx = make_dm_ctx(recipe, 4, 4, tp, false);
  51. ctx.recipe_name = "sg".to_string();
  52. squash(&build_docker_command(&ctx, node, head).unwrap().join(" "))
  53. }
  54. #[test]
  55. fn sglang_host_ip() {
  56. let cmd = srun(&sglang_recipe(), &tcls().nodes[0], true);
  57. assert!(cmd.contains("-e SGLANG_WORKER_IP=1"));
  58. assert!(!cmd.contains("VLLM_HOST_IP"));
  59. }
  60. #[test]
  61. fn sglang_head() {
  62. let cmd = srun(&sglang_recipe(), &tcls().nodes[0], true);
  63. assert!(cmd.contains("--model-path"));
  64. assert!(cmd.contains("org/sgl-model"));
  65. assert!(cmd.contains("--tp 4"));
  66. assert!(cmd.contains("--nnodes 4"));
  67. assert!(cmd.contains("--node-rank 0"));
  68. assert!(cmd.contains("--dist-init-addr 1:25000"));
  69. assert!(!cmd.contains("--master-addr"));
  70. assert!(!cmd.contains("--tensor-parallel-size"));
  71. assert!(!cmd.contains("--pipeline-parallel-size"));
  72. assert!(!cmd.contains("--distributed-executor-backend"));
  73. assert!(cmd.contains("-e TORCH_NCCL_ASYNC_ERROR_HANDLING=1"));
  74. assert!(
  75. !cmd.contains("-p "),
  76. "host networking: no port mapping expected"
  77. );
  78. assert!(cmd.contains("--port 8000"));
  79. assert!(cmd.contains("-e HF_HOME=/root/.cache/huggingface"));
  80. assert!(cmd.contains("-v /home/user/.cache/huggingface:/root/.cache/huggingface"));
  81. assert!(
  82. cmd.contains("--rm"),
  83. "SGLang default --rm should be present"
  84. );
  85. }
  86. #[test]
  87. fn sglang_worker() {
  88. let cmd = srun(&sglang_recipe(), &tcls().nodes[1], false);
  89. assert!(!cmd.contains("-p 8000:8000"));
  90. assert!(cmd.contains("--node-rank 1"));
  91. assert!(cmd.contains("--port 8000"));
  92. }
  93. #[test]
  94. fn sglang_entrypoint_model_path_order() {
  95. let cmd = srun(&sglang_recipe(), &tcls().nodes[0], true);
  96. let ep = cmd.find("--entrypoint sglang").unwrap();
  97. let ip = cmd.find("img").unwrap();
  98. let mp = cmd.find("--model-path").unwrap();
  99. let mdl = cmd.find("org/sgl-model").unwrap();
  100. let tp = cmd.find("--tp 4").unwrap();
  101. assert!(
  102. ep < ip && ip < mp && mp < mdl,
  103. "entrypoint flag, then image, then model-path, then model"
  104. );
  105. assert!(mdl < tp, "model before --tp");
  106. let port = cmd.find("--port 8000").unwrap();
  107. assert!(tp < port, "--tp before --port");
  108. }