Choose data, tensor, pipeline, and context parallel degrees using the supplied memory and communication model. Let d, t, p, and c be those four positive integer degrees. Let G be num_gpus, B be global_batch_size, S be model_state_bytes, and A be activation_bytes_per_sample. A feasible plan uses every GPU:
dtpc=G.The data degree must divide B, the context degree must divide sequence_length and meet min_context_parallel, and the product of tensor and context degrees must not exceed gpus_per_node. Per-GPU model-state memory Ms and activation memory Ma follow these equations, with ceiling brackets rounding up:
Ms=⌈tpS⌉. Ma=⌈tcA(B/d)⌉.Their sum must not exceed memory_per_gpu. The model's inter-node and intra-node communication estimates, Iout and Iin, are measured in bytes:
Iout=2Msdd−1+Mapp−1. Iin=2Ma(tt−1+cc−1).Choose the feasible plan with the smallest lexicographic score (Iout,Iin,p,−d,t,c). Return None if no plan fits; otherwise return a Python dictionary with data_parallel, tensor_parallel, pipeline_parallel, context_parallel, and estimated_memory_bytes as Python integers, plus inter_node_bytes and intra_node_bytes as Python floats.
Input: num_gpus = 4, gpus_per_node = 4, model_state_bytes = 400, activation_bytes_per_sample = 100, global_batch_size = 4, sequence_length = 8, memory_per_gpu = 300, min_context_parallel = 1
Output: {"data_parallel":1,"tensor_parallel":4,"pipeline_parallel":1,"context_parallel":1,"estimated_memory_bytes":200,"inter_node_bytes":0,"intra_node_bytes":150}
Explanation: Four-way tensor parallelism fits within one node, satisfies memory, and minimizes the ordered communication score.
Input: num_gpus = 8, gpus_per_node = 4, model_state_bytes = 800, activation_bytes_per_sample = 160, global_batch_size = 8, sequence_length = 16, memory_per_gpu = 600, min_context_parallel = 2
Output: {"data_parallel":1,"tensor_parallel":2,"pipeline_parallel":2,"context_parallel":2,"estimated_memory_bytes":520,"inter_node_bytes":160,"intra_node_bytes":640}
Input: num_gpus = 4, gpus_per_node = 2, model_state_bytes = 1000, activation_bytes_per_sample = 500, global_batch_size = 4, sequence_length = 8, memory_per_gpu = 1500, min_context_parallel = 1
Output: {"data_parallel":2,"tensor_parallel":2,"pipeline_parallel":1,"context_parallel":1,"estimated_memory_bytes":1000,"inter_node_bytes":500,"intra_node_bytes":500}
The % operator tests whether one integer divides another.
divmod gives a quotient and remainder without floating-point arithmetic.
Python compares tuples lexicographically.
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Choose data, tensor, pipeline, and context parallel degrees using the supplied memory and communication model. Let d, t, p, and c be those four positive integer degrees. Let G be num_gpus, B be global_batch_size, S be model_state_bytes, and A be activation_bytes_per_sample. A feasible plan uses every GPU:
dtpc=G.The data degree must divide B, the context degree must divide sequence_length and meet min_context_parallel, and the product of tensor and context degrees must not exceed gpus_per_node. Per-GPU model-state memory Ms and activation memory Ma follow these equations, with ceiling brackets rounding up:
Ms=⌈tpS⌉. Ma=⌈tcA(B/d)⌉.Their sum must not exceed memory_per_gpu. The model's inter-node and intra-node communication estimates, Iout and Iin, are measured in bytes:
Iout=2Msdd−1+Mapp−1. Iin=2Ma(tt−1+cc−1).Choose the feasible plan with the smallest lexicographic score (Iout,Iin,p,−d,t,c). Return None if no plan fits; otherwise return a Python dictionary with data_parallel, tensor_parallel, pipeline_parallel, context_parallel, and estimated_memory_bytes as Python integers, plus inter_node_bytes and intra_node_bytes as Python floats.
Input: num_gpus = 4, gpus_per_node = 4, model_state_bytes = 400, activation_bytes_per_sample = 100, global_batch_size = 4, sequence_length = 8, memory_per_gpu = 300, min_context_parallel = 1
Output: {"data_parallel":1,"tensor_parallel":4,"pipeline_parallel":1,"context_parallel":1,"estimated_memory_bytes":200,"inter_node_bytes":0,"intra_node_bytes":150}
Explanation: Four-way tensor parallelism fits within one node, satisfies memory, and minimizes the ordered communication score.
Input: num_gpus = 8, gpus_per_node = 4, model_state_bytes = 800, activation_bytes_per_sample = 160, global_batch_size = 8, sequence_length = 16, memory_per_gpu = 600, min_context_parallel = 2
Output: {"data_parallel":1,"tensor_parallel":2,"pipeline_parallel":2,"context_parallel":2,"estimated_memory_bytes":520,"inter_node_bytes":160,"intra_node_bytes":640}
Input: num_gpus = 4, gpus_per_node = 2, model_state_bytes = 1000, activation_bytes_per_sample = 500, global_batch_size = 4, sequence_length = 8, memory_per_gpu = 1500, min_context_parallel = 1
Output: {"data_parallel":2,"tensor_parallel":2,"pipeline_parallel":1,"context_parallel":1,"estimated_memory_bytes":1000,"inter_node_bytes":500,"intra_node_bytes":500}
The % operator tests whether one integer divides another.
divmod gives a quotient and remainder without floating-point arithmetic.
Python compares tuples lexicographically.
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number
Accepts: number