|
|
@@ -1,11 +1,17 @@
|
|
|
pub mod health;
|
|
|
|
|
|
-use crate::config::{Cluster, Config, NcclConfig, Node, Recipe, load_recipe, resolve_cluster};
|
|
|
-use crate::doctor::try_repaired_image;
|
|
|
-use crate::ssh::{run_ssh, run_ssh_follow, run_ssh_with_retry};
|
|
|
+use std::borrow::Cow;
|
|
|
+
|
|
|
use anyhow::{Context, Result};
|
|
|
use tokio::time::{Duration, sleep};
|
|
|
use tracing::info;
|
|
|
+
|
|
|
+use crate::{
|
|
|
+ config::{Cluster, Config, NcclConfig, Node, Recipe, load_recipe, resolve_cluster},
|
|
|
+ doctor::try_repaired_image,
|
|
|
+ ssh::{run_ssh, run_ssh_follow, run_ssh_with_retry},
|
|
|
+};
|
|
|
+
|
|
|
pub async fn serve(
|
|
|
config: &Config,
|
|
|
recipe_name: &str,
|
|
|
@@ -335,52 +341,62 @@ fn build_docker_command(
|
|
|
if !keep {
|
|
|
flags.push("--rm".to_string());
|
|
|
}
|
|
|
+
|
|
|
let mut cmd = vec![
|
|
|
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),
|
|
|
- format!("-e GLOO_SOCKET_IFNAME={}", nccl.socket_ifname),
|
|
|
- format!("-e TP_SOCKET_IFNAME={}", nccl.socket_ifname),
|
|
|
- format!("-e NCCL_IB_GID_INDEX={}", nccl.ib_gid_index),
|
|
|
- format!("-e HF_HOME=/root/.cache/huggingface"),
|
|
|
format!("-v {}:/root/.cache/huggingface", cache_dir),
|
|
|
];
|
|
|
- if is_sglang {
|
|
|
- cmd.push(format!("-e SGLANG_WORKER_IP={}", node.ib_ip));
|
|
|
- } else {
|
|
|
- cmd.push(format!("-e VLLM_HOST_IP={}", node.ib_ip));
|
|
|
+
|
|
|
+ let mut env = vec![("HF_HOME", Cow::Borrowed("/root/.cache/huggingface"))];
|
|
|
+ if nnodes > 1 {
|
|
|
+ let worker_ip = Cow::Borrowed(node.ib_ip.as_str());
|
|
|
+ if is_sglang {
|
|
|
+ env.push(("SGLANG_WORKER_IP", worker_ip));
|
|
|
+ } else {
|
|
|
+ env.push(("VLLM_HOST_IP", worker_ip));
|
|
|
+ }
|
|
|
+ let nccl_socket_ifname = nccl.socket_ifname.as_str();
|
|
|
+ env.extend([
|
|
|
+ ("NCCL_IB_DISABLE", format!("{}", nccl.ib_disable).into()),
|
|
|
+ ("NCCL_IB_HCA", nccl.ib_hca.as_str().into()),
|
|
|
+ ("NCCL_SOCKET_IFNAME", nccl_socket_ifname.into()),
|
|
|
+ ("GLOO_SOCKET_IFNAME", nccl_socket_ifname.into()),
|
|
|
+ ("TP_SOCKET_IFNAME", nccl_socket_ifname.into()),
|
|
|
+ ("NCCL_IB_GID_INDEX", nccl.ib_gid_index.to_string().into()),
|
|
|
+ ("MN_IF_NAME", nccl_socket_ifname.into()),
|
|
|
+ ("UCX_NET_DEVICES", nccl_socket_ifname.into()),
|
|
|
+ ("OMPI_MCA_btl_tcp_if_include", nccl_socket_ifname.into()),
|
|
|
+ ("OMP_NUM_THREADS", "4".into()),
|
|
|
+ ("NCCL_IGNORE_CPU_AFFINITY", "1".into()),
|
|
|
+ ("NCCL_NET", "IB".into()),
|
|
|
+ ("NCCL_DEBUG", "WARN".into()),
|
|
|
+ ]);
|
|
|
}
|
|
|
- cmd.push(format!("-e MN_IF_NAME={}", nccl.socket_ifname));
|
|
|
- cmd.push(format!("-e UCX_NET_DEVICES={}", nccl.socket_ifname));
|
|
|
- cmd.push(format!(
|
|
|
- "-e OMPI_MCA_btl_tcp_if_include={}",
|
|
|
- nccl.socket_ifname
|
|
|
- ));
|
|
|
- cmd.push("-e OMP_NUM_THREADS=4".to_string());
|
|
|
- cmd.push("-e NCCL_IGNORE_CPU_AFFINITY=1".to_string());
|
|
|
- cmd.push("-e NCCL_NET=IB".to_string());
|
|
|
- cmd.push("-e NCCL_DEBUG=WARN".to_string());
|
|
|
if is_head {
|
|
|
- cmd.push("-e VLLM_LOGGING_COLOR=1".to_string());
|
|
|
- cmd.push("-e TERM=xterm-256color".to_string());
|
|
|
+ env.push(("VLLM_LOGGING_COLOR", "1".into()));
|
|
|
+ env.push(("TERM", "xterm-256color".into()));
|
|
|
}
|
|
|
for (k, v) in &recipe.env {
|
|
|
- cmd.push(format!("-e {}={}", k, v));
|
|
|
- }
|
|
|
- if is_head {
|
|
|
- cmd.push(format!("-p {}:{}", recipe.port, recipe.port));
|
|
|
+ env.push((k.as_str(), v.as_str().into()));
|
|
|
}
|
|
|
cmd.push(format!("--name sm121_{}_{}", recipe_name, node.rank));
|
|
|
cmd.push(format!("--label sm121.recipe={}", recipe_name));
|
|
|
cmd.push(format!("--label sm121.rank={}", node.rank));
|
|
|
if recipe.distributed_backend == "ray" {
|
|
|
- cmd.push(format!("-e RAY_ADDRESS={}:6379", cluster.master_ib_ip));
|
|
|
- cmd.push(format!("-e RAY_PORT={}", recipe.port));
|
|
|
- cmd.push(format!("-e RAY_NODE_IP_ADDRESS={}", node.ib_ip));
|
|
|
- cmd.push(format!("-e RAY_OVERRIDE_NODE_IP_ADDRESS={}", node.ib_ip));
|
|
|
+ env.push((
|
|
|
+ "RAY_ADDRESS",
|
|
|
+ format!("{}:6379", cluster.master_ib_ip).into(),
|
|
|
+ ));
|
|
|
+ env.push(("RAY_PORT", "6379".into()));
|
|
|
+ env.push(("RAY_NODE_IP_ADDRESS", node.ib_ip.as_str().into()));
|
|
|
+ env.push(("RAY_OVERRIDE_NODE_IP_ADDRESS", node.ib_ip.as_str().into()));
|
|
|
+ }
|
|
|
+ for (k, v) in env {
|
|
|
+ cmd.push(format!("-e {k}={v}"));
|
|
|
}
|
|
|
+
|
|
|
cmd.push(recipe.docker_image.clone());
|
|
|
+
|
|
|
if !recipe.entrypoint.is_empty() {
|
|
|
let mut ep = recipe.entrypoint.clone();
|
|
|
if ep.len() >= 3 && ep[ep.len() - 2] == "-c" {
|
|
|
@@ -389,13 +405,14 @@ fn build_docker_command(
|
|
|
}
|
|
|
cmd.extend(ep);
|
|
|
}
|
|
|
+
|
|
|
if is_sglang {
|
|
|
cmd.push("--model-path".to_string());
|
|
|
- cmd.push(recipe.model.clone());
|
|
|
- } else {
|
|
|
- cmd.push(recipe.model.clone());
|
|
|
}
|
|
|
+ cmd.push(recipe.model.clone());
|
|
|
+
|
|
|
cmd.extend(recipe.args.clone());
|
|
|
+
|
|
|
let mut flags: Vec<String> = match recipe.distributed_backend.as_str() {
|
|
|
"ray" | "mp" if is_sglang => vec![
|
|
|
"--tp".into(),
|
|
|
@@ -440,5 +457,6 @@ fn build_docker_command(
|
|
|
cmd.push(recipe.port.to_string());
|
|
|
cmd
|
|
|
}
|
|
|
+
|
|
|
#[cfg(test)]
|
|
|
mod tests;
|