-
Notifications
You must be signed in to change notification settings - Fork 132
Add parallelism_auto flag to automatically set dp, tp and micro batch size
#516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 16 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
3f48d73
Implement --auto-parallelism
pefontana 653d0eb
parallelism_data.json
pefontana 01a6714
Merge branch 'main' into hardcode-parallelism-data
pefontana b541cc5
simplify code
pefontana 4a6e1d2
Merge remote-tracking branch 'origin/hardcode-parallelism-data' into …
pefontana 3af705e
clippy
pefontana 9303f99
Merge branch 'main' into hardcode-parallelism-data
pefontana 27f4ed5
add parallelism_data.json to Garnix
pefontana a8d5330
add hardware type to json
pefontana f265de9
update .json
pefontana 1d3aafd
Fallback: read from /proc/driver/nvidia
pefontana 50762e5
restore scripts/train-solana-test.sh
pefontana f6c1c7a
update documentation
pefontana 42fd012
Change micro_batch_size for Meta-Llama-3.1 to 1
pefontana 1695b93
nit
pefontana 5175723
look data-parallelism.json in HF repo
pefontana 8f6d14e
change json format
pefontana 6644c67
nvml_wrapper
pefontana ec28547
Merge branch 'main' into hardcode-parallelism-data
pefontana fdf4f0d
se tch for GPU count (respects CUDA_VISIBLE_DEVICES)
pefontana 1a454c5
Merge branch 'main' into hardcode-parallelism-data
pefontana 6114eba
Merge branch 'main' into hardcode-parallelism-data
pefontana 22f7b26
Merge branch 'main' into hardcode-parallelism-data
pefontana 8a4dabd
Merge branch 'main' into hardcode-parallelism-data
pefontana 6ac2e70
Merge branch 'main' into hardcode-parallelism-data
pefontana 4dc974b
Merge branch 'main' into hardcode-parallelism-data
pefontana 6f4ae53
Merge branch 'main' into hardcode-parallelism-data
pefontana e1f7276
Merge branch 'main' into hardcode-parallelism-data
pefontana File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| mod cli; | ||
| mod client; | ||
| mod fetch_data; | ||
| pub mod parallelism_lookup; | ||
| mod protocol; | ||
| mod state; | ||
| mod tui; | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "_doc (HuggingFace repo)": { | ||
| "gpu type from nvidia-smi": { | ||
| "numember of gpus": { | ||
| "dp": 0, | ||
| "tp": 0, | ||
| "micro_batch_size": 0 | ||
| } | ||
| } | ||
| }, | ||
| "emozilla/llama2-20m-init": { | ||
| "H100": { | ||
| "1": { "dp": 1, "tp": 1, "micro_batch_size": 1 }, | ||
| "8": { "dp": 1, "tp": 1, "micro_batch_size": 1 } | ||
| } | ||
| }, | ||
| "TinyLlama/TinyLlama-1.1B-Chat-v0.4": { | ||
| "H100": { | ||
| "1": { "dp": 1, "tp": 1, "micro_batch_size": 8 }, | ||
| "8": { "dp": 8, "tp": 1, "micro_batch_size": 8 } | ||
| } | ||
| }, | ||
| "NousResearch/Meta-Llama-3.1-8B": { | ||
| "H100": { | ||
| "1": { "dp": 1, "tp": 1, "micro_batch_size": 1 }, | ||
| "8": { "dp": 8, "tp": 1, "micro_batch_size": 4 } | ||
| } | ||
| }, | ||
| "deepseek-ai/DeepSeek-V2-Lite": { | ||
| "H100": { | ||
| "1": { "dp": 1, "tp": 1, "micro_batch_size": 1 }, | ||
| "8": { "dp": 4, "tp": 2, "micro_batch_size": 2 } | ||
| } | ||
| }, | ||
| "NousResearch/Hermes-4-70B": { | ||
| "H100": { | ||
| "8": { "dp": 1, "tp": 8, "micro_batch_size": 1 } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| use anyhow::Result; | ||
| use hf_hub::{Repo, RepoType}; | ||
| use serde::Deserialize; | ||
| use std::collections::HashMap; | ||
| use std::process::Command; | ||
| use tracing::{info, warn}; | ||
|
|
||
| const PARALLELISM_DATA: &str = include_str!("parallelism_data.json"); | ||
| const REMOTE_CONFIG_FILENAME: &str = "parallelism_data.json"; | ||
|
|
||
| #[derive(Debug, Clone, Copy, Deserialize)] | ||
| pub struct ParallelismConfig { | ||
| pub dp: usize, | ||
| pub tp: usize, | ||
| pub micro_batch_size: usize, | ||
| } | ||
|
|
||
| // Table format: model -> gpu_type -> num_gpus -> config | ||
| type Table = HashMap<String, HashMap<String, HashMap<String, ParallelismConfig>>>; | ||
|
|
||
| fn get_gpu_type() -> String { | ||
| // Try nvidia-smi first | ||
| let raw_gpu_name = Command::new("nvidia-smi") | ||
| .args(["--query-gpu=name", "--format=csv,noheader"]) | ||
| .output() | ||
| .ok() | ||
| .and_then(|o| String::from_utf8(o.stdout).ok()) | ||
| .and_then(|s| s.lines().next().map(|l| l.trim().to_string())) | ||
| .filter(|s| !s.is_empty()) | ||
| // Fallback: read from /proc/driver/nvidia (works in containers without nvidia-smi) | ||
| .or_else(|| { | ||
| std::fs::read_dir("/proc/driver/nvidia/gpus") | ||
| .ok()? | ||
| .filter_map(|e| e.ok()) | ||
| .next() | ||
| .and_then(|entry| { | ||
| let info_path = entry.path().join("information"); | ||
| std::fs::read_to_string(info_path).ok() | ||
| }) | ||
| .and_then(|content| { | ||
| content | ||
| .lines() | ||
| .find(|line| line.starts_with("Model:")) | ||
| .map(|line| line.trim_start_matches("Model:").trim().to_string()) | ||
| }) | ||
| }) | ||
| .unwrap_or_default(); | ||
|
|
||
| // Normalize GPU name to match table keys | ||
| if raw_gpu_name.to_uppercase().contains("H200") { | ||
| "H200".to_string() | ||
| } else if raw_gpu_name.to_uppercase().contains("H100") { | ||
| "H100".to_string() | ||
| } else { | ||
| raw_gpu_name | ||
| } | ||
| } | ||
|
|
||
| /// Try to load parallelism config from the model's HuggingFace repo | ||
| fn load_from_model_repo(model_repo_id: &str) -> Option<Table> { | ||
| let token = std::env::var("HF_TOKEN").ok(); | ||
|
|
||
| let api = hf_hub::api::sync::ApiBuilder::new() | ||
| .with_token(token) | ||
| .build() | ||
| .ok()? | ||
| .repo(Repo::new(model_repo_id.to_string(), RepoType::Model)); | ||
|
|
||
| let path = api.get(REMOTE_CONFIG_FILENAME).ok()?; | ||
| let content = std::fs::read_to_string(path).ok()?; | ||
| serde_json::from_str(&content).ok() | ||
| } | ||
|
|
||
| /// Lookup config in a table | ||
| fn lookup_in_table( | ||
| table: &Table, | ||
| model_repo_id: &str, | ||
| gpu_type: &str, | ||
| num_gpus: usize, | ||
| ) -> Option<ParallelismConfig> { | ||
| table | ||
| .get(model_repo_id) | ||
| .and_then(|g| g.get(gpu_type)) | ||
| .and_then(|n| n.get(&num_gpus.to_string())) | ||
| .copied() | ||
| } | ||
|
|
||
| /// Load the compiled parallelism table | ||
| fn load_compiled_table() -> Result<Table> { | ||
| serde_json::from_str(PARALLELISM_DATA) | ||
| .map_err(|e| anyhow::anyhow!("Failed to parse compiled parallelism data: {}", e)) | ||
| } | ||
|
|
||
| pub fn lookup(model_repo_id: &str) -> Result<ParallelismConfig> { | ||
| let num_gpus = tch::Cuda::device_count() as usize; | ||
| let gpu_type = get_gpu_type(); | ||
| info!("Detected {} x {} GPU(s)", num_gpus, gpu_type); | ||
|
|
||
| // Try model's own config first | ||
| if let Some(table) = load_from_model_repo(model_repo_id) { | ||
| if let Some(config) = lookup_in_table(&table, model_repo_id, &gpu_type, num_gpus) { | ||
| info!( | ||
| "Using parallelism config from model repo '{}'", | ||
| model_repo_id | ||
| ); | ||
| return Ok(config); | ||
| } | ||
| } | ||
|
|
||
| // Fall back to compiled table | ||
| warn!( | ||
| "No parallelism config found in model repo '{}', using compiled defaults", | ||
| model_repo_id | ||
| ); | ||
|
|
||
| let table = load_compiled_table()?; | ||
| lookup_in_table(&table, model_repo_id, &gpu_type, num_gpus).ok_or_else(|| { | ||
| anyhow::anyhow!( | ||
| "No config for {} x {} with model '{}'", | ||
| num_gpus, | ||
| gpu_type, | ||
| model_repo_id | ||
| ) | ||
| }) | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
have you considered using the
nvml_wrappercrate instead of shelling out / reading /proc/fs stuff? we can grab gpu count from there too 🤷 and assert that they're all the same GPU for sanity checking :Dwe use this in some of the metrics stuff already -
it would be something like:
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Ari!
I add it and works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just changed the
let device_count = nvml.device_count()?;because was not taking into accountCUDA_VISIBLE_DEVICESenv var