Spaces:
Sleeping
Sleeping
| import { describe, expect, it } from 'vitest' | |
| import { | |
| a100_80gb, | |
| analyzeCluster, | |
| b300, | |
| cluster64GPU, | |
| h100_sxm, | |
| llama70B, | |
| llama7B, | |
| llama31_405B, | |
| olmo3_32B, | |
| singleNode8GPU, | |
| trinityLarge400B, | |
| type ClusterConfig, | |
| type TrainingConfig, | |
| } from '../src/lib/trainingClusterModel' | |
| const baselineTraining: TrainingConfig = { | |
| microBatchSize: 1, | |
| seqLength: 2048, | |
| gradAccumSteps: 8, | |
| precision: 'bf16', | |
| activationCheckpointing: true, | |
| optimizer: 'adamw', | |
| } | |
| describe('trainingClusterModel', () => { | |
| it('fits Llama 2 7B on 8x A100 80GB with TP=8 and derived DP=1', () => { | |
| const analysis = analyzeCluster(llama7B(), baselineTraining, singleNode8GPU(a100_80gb()), { | |
| tp: 8, | |
| pp: 1, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: false, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 0, | |
| }) | |
| expect(analysis.feasible).toBe(true) | |
| expect(analysis.derivedParallelism.dp).toBe(1) | |
| expect(analysis.memoryBreakdown.totalGB).toBeLessThan(80) | |
| }) | |
| it('marks Llama 2 70B on 8x A100 80GB as infeasible for unsharded Adam training', () => { | |
| const analysis = analyzeCluster(llama70B(), baselineTraining, singleNode8GPU(a100_80gb()), { | |
| tp: 8, | |
| pp: 1, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: false, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 0, | |
| }) | |
| expect(analysis.feasible).toBe(false) | |
| expect(analysis.infeasibilityReason).toContain('exceeding 80 GB of HBM') | |
| }) | |
| it('keeps MFU in a realistic range for a balanced 64x H100 dense run', () => { | |
| const analysis = analyzeCluster( | |
| llama70B(), | |
| { | |
| ...baselineTraining, | |
| seqLength: 4096, | |
| gradAccumSteps: 16, | |
| }, | |
| cluster64GPU(h100_sxm()), | |
| { | |
| tp: 4, | |
| pp: 4, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 1, | |
| }, | |
| ) | |
| expect(analysis.feasible).toBe(true) | |
| expect(analysis.derivedParallelism.dp).toBe(4) | |
| expect(analysis.throughput.mfu).toBeGreaterThan(0.3) | |
| expect(analysis.throughput.mfu).toBeLessThanOrEqual(0.62) | |
| }) | |
| it('reduces activation memory when CP increases and adds CP communication', () => { | |
| const withoutCp = analyzeCluster( | |
| llama70B(), | |
| { | |
| ...baselineTraining, | |
| seqLength: 4096, | |
| }, | |
| cluster64GPU(h100_sxm()), | |
| { | |
| tp: 2, | |
| pp: 2, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 1, | |
| }, | |
| ) | |
| const withCp = analyzeCluster( | |
| llama70B(), | |
| { | |
| ...baselineTraining, | |
| seqLength: 4096, | |
| }, | |
| cluster64GPU(h100_sxm()), | |
| { | |
| tp: 2, | |
| pp: 2, | |
| cp: 4, | |
| ep: 1, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 1, | |
| }, | |
| ) | |
| expect(withCp.memoryBreakdown.activationsGB).toBeLessThan(withoutCp.memoryBreakdown.activationsGB) | |
| expect(withCp.communication.cp.totalVolumePerStepGB).toBeGreaterThan(0) | |
| }) | |
| it('reduces OLMo memory with HSDP shard groups compared with plain DP', () => { | |
| const cluster = { | |
| ...cluster64GPU(h100_sxm()), | |
| numNodes: 128, | |
| nodesPerRack: 16, | |
| } | |
| const plain = analyzeCluster( | |
| olmo3_32B(), | |
| { | |
| microBatchSize: 1, | |
| seqLength: 8192, | |
| gradAccumSteps: 1, | |
| precision: 'bf16', | |
| activationCheckpointing: true, | |
| optimizer: 'adamw', | |
| }, | |
| cluster, | |
| { | |
| tp: 1, | |
| pp: 1, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: false, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 0, | |
| }, | |
| ) | |
| const hsdp = analyzeCluster( | |
| olmo3_32B(), | |
| { | |
| microBatchSize: 1, | |
| seqLength: 8192, | |
| gradAccumSteps: 1, | |
| precision: 'bf16', | |
| activationCheckpointing: true, | |
| optimizer: 'adamw', | |
| }, | |
| cluster, | |
| { | |
| tp: 1, | |
| pp: 1, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 256, | |
| zeroStage: 3, | |
| }, | |
| ) | |
| expect(hsdp.derivedParallelism.replicaGroups).toBe(4) | |
| expect(hsdp.memoryBreakdown.totalGB).toBeLessThan(plain.memoryBreakdown.totalGB) | |
| expect(hsdp.communication.fsdp.totalVolumePerStepGB).toBeGreaterThan(0) | |
| }) | |
| it('models Trinity as total-parameter-heavy but active-compute-light', () => { | |
| const analysis = analyzeCluster( | |
| trinityLarge400B(), | |
| { | |
| microBatchSize: 1, | |
| seqLength: 8192, | |
| gradAccumSteps: 8, | |
| precision: 'bf16', | |
| activationCheckpointing: true, | |
| optimizer: 'muon', | |
| }, | |
| trinityCluster(), | |
| { | |
| tp: 1, | |
| pp: 1, | |
| cp: 1, | |
| ep: 8, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 128, | |
| zeroStage: 3, | |
| }, | |
| ) | |
| expect(analysis.totalParams).toBeGreaterThan(300_000_000_000) | |
| expect(analysis.activeParamsPerToken).toBe(13_000_000_000) | |
| expect(analysis.communication.ep.totalVolumePerStepGB).toBeGreaterThan(0) | |
| expect(analysis.communication.ep.usesInterNode).toBe(false) | |
| expect(new Set(analysis.gpuMap.map((gpu) => gpu.epLane))).toEqual( | |
| new Set([0, 1, 2, 3, 4, 5, 6, 7]), | |
| ) | |
| }) | |
| it('derives DP for Llama 3.1 405B from world size and 4D parallelism', () => { | |
| const analysis = analyzeCluster( | |
| llama31_405B(), | |
| { | |
| microBatchSize: 1, | |
| seqLength: 8192, | |
| gradAccumSteps: 16, | |
| precision: 'bf16', | |
| activationCheckpointing: true, | |
| optimizer: 'adamw', | |
| }, | |
| llama405Cluster(), | |
| { | |
| tp: 8, | |
| pp: 16, | |
| cp: 1, | |
| ep: 1, | |
| distributedOptimizer: true, | |
| fsdpShardGroupSize: 0, | |
| zeroStage: 1, | |
| }, | |
| ) | |
| expect(analysis.derivedParallelism.dp).toBe(128) | |
| expect(analysis.feasible).toBe(true) | |
| expect(analysis.communication.tp.totalVolumePerStepGB).toBeGreaterThan(0) | |
| expect(analysis.communication.pp.totalVolumePerStepGB).toBeGreaterThan(0) | |
| expect(analysis.communication.fsdp.totalVolumePerStepGB).toBe(0) | |
| }) | |
| }) | |
| function llama405Cluster(): ClusterConfig { | |
| return { | |
| gpuType: h100_sxm(), | |
| gpusPerNode: 8, | |
| numNodes: 2048, | |
| intraNodeBandwidthGBs: 900, | |
| interNodeBandwidthGBs: 50, | |
| nodesPerRack: 16, | |
| rackLabel: 'rack', | |
| nodeLabel: 'GPU host', | |
| podLabel: 'rack', | |
| } | |
| } | |
| function trinityCluster(): ClusterConfig { | |
| return { | |
| gpuType: b300(), | |
| gpusPerNode: 8, | |
| numNodes: 256, | |
| intraNodeBandwidthGBs: 900, | |
| interNodeBandwidthGBs: 50, | |
| nodesPerRack: 9, | |
| rackLabel: 'rack', | |
| nodeLabel: 'GPU host', | |
| podLabel: 'rack', | |
| } | |
| } | |