|
|
@@ -11,6 +11,7 @@ pub async fn serve(
|
|
|
config: &Config,
|
|
|
recipe_name: &str,
|
|
|
cluster_name: &str,
|
|
|
+ keep: bool,
|
|
|
dry_run: bool,
|
|
|
) -> Result<()> {
|
|
|
let recipe = load_recipe(recipe_name).await?;
|
|
|
@@ -47,6 +48,7 @@ pub async fn serve(
|
|
|
recipe_name,
|
|
|
&recipe,
|
|
|
cache_dir,
|
|
|
+ keep,
|
|
|
dry_run,
|
|
|
)
|
|
|
.await?;
|
|
|
@@ -220,6 +222,7 @@ pub async fn health_check(config: &Config, cluster: &Cluster, dry_run: bool) ->
|
|
|
}
|
|
|
|
|
|
/// Starts containers on all nodes in parallel.
|
|
|
+#[allow(clippy::too_many_arguments)]
|
|
|
async fn start_cluster(
|
|
|
config: &Config,
|
|
|
cluster: &Cluster,
|
|
|
@@ -227,6 +230,7 @@ async fn start_cluster(
|
|
|
recipe_name: &str,
|
|
|
recipe: &Recipe,
|
|
|
cache_dir: String,
|
|
|
+ keep: bool,
|
|
|
dry_run: bool,
|
|
|
) -> Result<()> {
|
|
|
let nnodes = cluster.nodes.len() as u32;
|
|
|
@@ -258,7 +262,7 @@ async fn start_cluster(
|
|
|
let _ = run_ssh(&config, &node, cleanup, dry).await;
|
|
|
}
|
|
|
let cmd = build_docker_command(
|
|
|
- &cluster, &nccl, &recipe, &rn, &node, is_head, pp_size, nnodes, &cd,
|
|
|
+ &cluster, &nccl, &recipe, &rn, &node, is_head, pp_size, nnodes, &cd, keep,
|
|
|
)
|
|
|
.join(" ");
|
|
|
let result = run_ssh_with_retry(&config, &node, cmd, dry, 2).await;
|
|
|
@@ -306,11 +310,16 @@ fn build_docker_command(
|
|
|
pp_size: u32,
|
|
|
nnodes: u32,
|
|
|
cache_dir: &str,
|
|
|
+ keep: bool,
|
|
|
) -> Vec<String> {
|
|
|
let is_sglang = recipe.engine == "sglang";
|
|
|
|
|
|
+ let mut flags = vec!["--gpus all", "--ipc=host", "--privileged", "--network=host"];
|
|
|
+ if !keep {
|
|
|
+ flags.push("--rm");
|
|
|
+ }
|
|
|
let mut cmd = vec![
|
|
|
- "docker run -d --gpus all --ipc=host --privileged --network=host".to_string(),
|
|
|
+ format!("docker run -d {}", flags.join(" ")),
|
|
|
format!("-e NCCL_IB_DISABLE={}", nccl.ib_disable),
|
|
|
format!("-e NCCL_IB_HCA={}", nccl.ib_hca),
|
|
|
format!("-e NCCL_SOCKET_IFNAME={}", nccl.socket_ifname),
|