GPU Tests / Check GPU Availability (push) Successful in 0s
GPU Tests / Metal Tests (push) Has been skipped
CI / Format Check (push) Failing after 6s
CI / Clippy Check (push) Failing after 7s
Performance Benchmarks / Run Benchmarks (push) Failing after 7s
GPU Tests / CUDA Tests (11.8) (push) Has been skipped
GPU Tests / CUDA Tests (12.1) (push) Has been skipped
CI / Build (ubuntu-latest) (push) Failing after 7s
Documentation / Build User Guide (push) Successful in 8s
CI / Build (macos-latest) (push) Failing after 9s
CI / Test (macos-latest) (push) Has been skipped
CI / Test (ubuntu-latest) (push) Has been skipped
CI / Python Bindings (maturin) (macos-latest) (push) Has been skipped
CI / Python Bindings (maturin) (ubuntu-latest) (push) Has been skipped
CI / WASM Build + Size Check (push) Has been skipped
CI / Distributed Training Tests (push) Has been skipped
CI / Build CPU-Only (Explicit) (push) Failing after 43s
Documentation / Build API Documentation (push) Failing after 48s
CI / CI Success (push) Failing after 0s
Demos: - rtx-distllm-demo: real rtx-tensor weights per shard, real scaled-dot-product attention forward, metrics measured (Instant) instead of hardcoded constants; network topology remains a documented simulation fed by real tensor byte sizes. - rtx-model-zoo: MockInferenceEngine deleted; RealInferenceEngine loads a tiny real transformer into rtx_inference::InferenceEngine and runs genuine engine.infer per request; domain outputs are explicitly- labeled toy proxies derived from real output tokens. - rtx-inference-profiler: mock models deleted; profiles real matmul/softmax pipelines on rtx-tensor with measured latency/memory. Inference-path bugs the demos surfaced (fixed here): - ForwardPass::apply_embedding misused Tensor::gather for the embedding lookup — gather returns the indices' shape, silently dropping the hidden dim and breaking every downstream broadcast. Now uses the existing Tensor::embedding_lookup ([vocab,hidden] x [batch,seq] -> [batch,seq,hidden]). - Attention weight lookup accepts both self_attn. (HF-LLaMA) and attention. prefixes; final layer norm accepts norm.weight / model.norm.weight / ln_f.weight aliases. - Integration fixture gains the final norm weight; the previously always-failing engine tests now pass (8/8 model_loading_test). End-to-end inference through the real engine now works for the first time — verified via model_zoo_demo producing real forward-pass outputs across all categories. Co-Authored-By: Claude Fable 5 <[email protected]>
720 lines
20 KiB
Rust
720 lines
20 KiB
Rust
//! Sample data and configurations for DistributedLLM demo.
|
|
//!
|
|
//! This module provides pre-configured model, cluster, and inference
|
|
//! settings for demonstration and testing purposes.
|
|
|
|
use distllm_shared::{
|
|
ClusterConfig, CommBackend, DataType, GenerationConfig, InferenceRequest, KVCacheConfig,
|
|
ModelConfig, NetworkTopology, NodeConfig, ParallelismConfig, PipelineSchedule, SamplingParams,
|
|
};
|
|
|
|
// ============================================================================
|
|
// Model Configurations
|
|
// ============================================================================
|
|
|
|
/// A small model configuration used for **real tensor compute** demo runs.
|
|
///
|
|
/// The larger configs below (`llama_70b_config`, `llama_405b_config`, ...)
|
|
/// describe genuinely trillion-parameter-scale models: their weight tensors
|
|
/// are far too large to actually allocate (would require hundreds of GB of
|
|
/// RAM per shard). They remain useful for cluster-planning /
|
|
/// memory-estimation code paths that only read `ModelConfig` fields and
|
|
/// never allocate real weights. Anywhere this demo performs *real*
|
|
/// `Tensor::randn` weight allocation and real attention compute
|
|
/// (`ModelShard::load`, `DistributedLLM::generate`, `run_demo`), this small
|
|
/// config (or something similarly sized) should be used instead, so the
|
|
/// real compute stays representative without exhausting host memory.
|
|
#[must_use]
|
|
pub fn tiny_realcompute_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "tiny-realcompute-demo".to_string(),
|
|
num_params: 0.05,
|
|
num_layers: 8,
|
|
hidden_dim: 256,
|
|
num_heads: 8,
|
|
num_kv_heads: 8,
|
|
intermediate_dim: 512,
|
|
vocab_size: 32000,
|
|
max_seq_len: 4096,
|
|
head_dim: 32,
|
|
rope_theta: 10000.0,
|
|
dtype: DataType::Float32,
|
|
}
|
|
}
|
|
|
|
/// LLaMA 7B model configuration.
|
|
#[must_use]
|
|
pub fn llama_7b_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "llama-7b".to_string(),
|
|
num_params: 7.0,
|
|
num_layers: 32,
|
|
hidden_dim: 4096,
|
|
num_heads: 32,
|
|
num_kv_heads: 32,
|
|
intermediate_dim: 11008,
|
|
vocab_size: 32000,
|
|
max_seq_len: 4096,
|
|
head_dim: 128,
|
|
rope_theta: 10000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
/// LLaMA 13B model configuration.
|
|
#[must_use]
|
|
pub fn llama_13b_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "llama-13b".to_string(),
|
|
num_params: 13.0,
|
|
num_layers: 40,
|
|
hidden_dim: 5120,
|
|
num_heads: 40,
|
|
num_kv_heads: 40,
|
|
intermediate_dim: 13824,
|
|
vocab_size: 32000,
|
|
max_seq_len: 4096,
|
|
head_dim: 128,
|
|
rope_theta: 10000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
/// LLaMA 70B model configuration.
|
|
#[must_use]
|
|
pub fn llama_70b_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "llama-70b".to_string(),
|
|
num_params: 70.0,
|
|
num_layers: 80,
|
|
hidden_dim: 8192,
|
|
num_heads: 64,
|
|
num_kv_heads: 8, // GQA
|
|
intermediate_dim: 28672,
|
|
vocab_size: 32000,
|
|
max_seq_len: 4096,
|
|
head_dim: 128,
|
|
rope_theta: 10000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
/// LLaMA 405B model configuration (requires large cluster).
|
|
#[must_use]
|
|
pub fn llama_405b_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "llama-405b".to_string(),
|
|
num_params: 405.0,
|
|
num_layers: 126,
|
|
hidden_dim: 16384,
|
|
num_heads: 128,
|
|
num_kv_heads: 8, // GQA
|
|
intermediate_dim: 53248,
|
|
vocab_size: 128256,
|
|
max_seq_len: 131072,
|
|
head_dim: 128,
|
|
rope_theta: 500000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
/// Mixtral 8x7B MoE model configuration.
|
|
#[must_use]
|
|
pub fn mixtral_8x7b_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "mixtral-8x7b".to_string(),
|
|
num_params: 46.7, // Active params per forward pass
|
|
num_layers: 32,
|
|
hidden_dim: 4096,
|
|
num_heads: 32,
|
|
num_kv_heads: 8, // GQA
|
|
intermediate_dim: 14336,
|
|
vocab_size: 32000,
|
|
max_seq_len: 32768,
|
|
head_dim: 128,
|
|
rope_theta: 1000000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
/// GPT-4 scale model configuration (hypothetical).
|
|
#[must_use]
|
|
pub fn gpt4_scale_config() -> ModelConfig {
|
|
ModelConfig {
|
|
name: "gpt4-scale".to_string(),
|
|
num_params: 1760.0, // 1.76T params
|
|
num_layers: 120,
|
|
hidden_dim: 25600,
|
|
num_heads: 200,
|
|
num_kv_heads: 25, // GQA
|
|
intermediate_dim: 102400,
|
|
vocab_size: 128000,
|
|
max_seq_len: 128000,
|
|
head_dim: 128,
|
|
rope_theta: 500000.0,
|
|
dtype: DataType::BFloat16,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Cluster Configurations
|
|
// ============================================================================
|
|
|
|
/// Single Mac Studio configuration.
|
|
#[must_use]
|
|
pub fn single_node_cluster() -> ClusterConfig {
|
|
ClusterConfig {
|
|
name: "single-mac-studio".to_string(),
|
|
nodes: vec![NodeConfig {
|
|
id: 0,
|
|
hostname: "localhost".to_string(),
|
|
memory_gb: 192.0,
|
|
cpu_cores: 24,
|
|
gpu_type: None,
|
|
gpu_memory_gb: None,
|
|
network: CommBackend::PCIe,
|
|
}],
|
|
topology: NetworkTopology::Ring,
|
|
total_memory_gb: 192.0,
|
|
}
|
|
}
|
|
|
|
/// 2-node Thunderbolt 5 cluster.
|
|
#[must_use]
|
|
pub fn two_node_cluster() -> ClusterConfig {
|
|
ClusterConfig {
|
|
name: "tb5-2node-cluster".to_string(),
|
|
nodes: (0..2)
|
|
.map(|i| NodeConfig {
|
|
id: i,
|
|
hostname: format!("mac-studio-{}", i),
|
|
memory_gb: 192.0,
|
|
cpu_cores: 24,
|
|
gpu_type: None,
|
|
gpu_memory_gb: None,
|
|
network: CommBackend::Thunderbolt5,
|
|
})
|
|
.collect(),
|
|
topology: NetworkTopology::Ring,
|
|
total_memory_gb: 384.0,
|
|
}
|
|
}
|
|
|
|
/// 4-node Thunderbolt 5 cluster.
|
|
#[must_use]
|
|
pub fn four_node_cluster() -> ClusterConfig {
|
|
ClusterConfig {
|
|
name: "tb5-4node-cluster".to_string(),
|
|
nodes: (0..4)
|
|
.map(|i| NodeConfig {
|
|
id: i,
|
|
hostname: format!("mac-studio-{}", i),
|
|
memory_gb: 192.0,
|
|
cpu_cores: 24,
|
|
gpu_type: None,
|
|
gpu_memory_gb: None,
|
|
network: CommBackend::Thunderbolt5,
|
|
})
|
|
.collect(),
|
|
topology: NetworkTopology::Ring,
|
|
total_memory_gb: 768.0,
|
|
}
|
|
}
|
|
|
|
/// 8-node Thunderbolt 5 cluster.
|
|
#[must_use]
|
|
pub fn eight_node_cluster() -> ClusterConfig {
|
|
ClusterConfig {
|
|
name: "tb5-8node-cluster".to_string(),
|
|
nodes: (0..8)
|
|
.map(|i| NodeConfig {
|
|
id: i,
|
|
hostname: format!("mac-studio-{}", i),
|
|
memory_gb: 192.0,
|
|
cpu_cores: 24,
|
|
gpu_type: None,
|
|
gpu_memory_gb: None,
|
|
network: CommBackend::Thunderbolt5,
|
|
})
|
|
.collect(),
|
|
topology: NetworkTopology::Mesh,
|
|
total_memory_gb: 1536.0,
|
|
}
|
|
}
|
|
|
|
/// 16-node heterogeneous cluster.
|
|
#[must_use]
|
|
pub fn sixteen_node_cluster() -> ClusterConfig {
|
|
ClusterConfig {
|
|
name: "hybrid-16node-cluster".to_string(),
|
|
nodes: (0..16)
|
|
.map(|i| NodeConfig {
|
|
id: i,
|
|
hostname: format!("node-{}", i),
|
|
memory_gb: if i < 8 { 192.0 } else { 96.0 },
|
|
cpu_cores: if i < 8 { 24 } else { 12 },
|
|
gpu_type: None,
|
|
gpu_memory_gb: None,
|
|
network: if i < 8 {
|
|
CommBackend::Thunderbolt5
|
|
} else {
|
|
CommBackend::Ethernet
|
|
},
|
|
})
|
|
.collect(),
|
|
topology: NetworkTopology::Tree,
|
|
total_memory_gb: 2304.0,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Parallelism Configurations
|
|
// ============================================================================
|
|
|
|
/// Single-node parallelism (no distribution).
|
|
#[must_use]
|
|
pub fn single_node_parallel_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 1,
|
|
pipeline_parallel: 1,
|
|
world_size: 1,
|
|
num_micro_batches: 1,
|
|
pipeline_schedule: PipelineSchedule::GPipe,
|
|
comm_backend: CommBackend::PCIe,
|
|
}
|
|
}
|
|
|
|
/// 2-node pipeline parallelism.
|
|
#[must_use]
|
|
pub fn two_node_parallel_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 1,
|
|
pipeline_parallel: 2,
|
|
world_size: 2,
|
|
num_micro_batches: 4,
|
|
pipeline_schedule: PipelineSchedule::OneForwardOneBackward,
|
|
comm_backend: CommBackend::Thunderbolt5,
|
|
}
|
|
}
|
|
|
|
/// 4-node pipeline parallelism.
|
|
#[must_use]
|
|
pub fn four_node_parallel_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 1,
|
|
pipeline_parallel: 4,
|
|
world_size: 4,
|
|
num_micro_batches: 8,
|
|
pipeline_schedule: PipelineSchedule::OneForwardOneBackward,
|
|
comm_backend: CommBackend::Thunderbolt5,
|
|
}
|
|
}
|
|
|
|
/// 4-node hybrid parallelism (2 TP x 2 PP).
|
|
#[must_use]
|
|
pub fn four_node_hybrid_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 2,
|
|
pipeline_parallel: 2,
|
|
world_size: 4,
|
|
num_micro_batches: 4,
|
|
pipeline_schedule: PipelineSchedule::InterleavedOneForwardOneBackward,
|
|
comm_backend: CommBackend::Thunderbolt5,
|
|
}
|
|
}
|
|
|
|
/// 8-node pipeline parallelism.
|
|
#[must_use]
|
|
pub fn eight_node_parallel_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 1,
|
|
pipeline_parallel: 8,
|
|
world_size: 8,
|
|
num_micro_batches: 16,
|
|
pipeline_schedule: PipelineSchedule::ZeroBubble,
|
|
comm_backend: CommBackend::Thunderbolt5,
|
|
}
|
|
}
|
|
|
|
/// 8-node hybrid parallelism (4 TP x 2 PP).
|
|
#[must_use]
|
|
pub fn eight_node_hybrid_config() -> ParallelismConfig {
|
|
ParallelismConfig {
|
|
tensor_parallel: 4,
|
|
pipeline_parallel: 2,
|
|
world_size: 8,
|
|
num_micro_batches: 8,
|
|
pipeline_schedule: PipelineSchedule::InterleavedOneForwardOneBackward,
|
|
comm_backend: CommBackend::Thunderbolt5,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Inference Requests
|
|
// ============================================================================
|
|
|
|
/// Simple chat inference request.
|
|
#[must_use]
|
|
pub fn chat_inference_request() -> InferenceRequest {
|
|
InferenceRequest {
|
|
prompt: "You are a helpful AI assistant.\n\nUser: Explain the theory of relativity in simple terms.\n\nAssistant:".to_string(),
|
|
max_tokens: 512,
|
|
temperature: 0.7,
|
|
top_p: 0.9,
|
|
top_k: 50,
|
|
frequency_penalty: 0.0,
|
|
presence_penalty: 0.0,
|
|
stop_sequences: vec!["User:".to_string()],
|
|
seed: Some(42),
|
|
stream: true,
|
|
}
|
|
}
|
|
|
|
/// Code completion request.
|
|
#[must_use]
|
|
pub fn code_completion_request() -> InferenceRequest {
|
|
InferenceRequest {
|
|
prompt: "```rust\n// Implement a parallel merge sort using Rayon\nfn parallel_merge_sort<T: Ord + Clone + Send>(arr: &mut [T]) {\n".to_string(),
|
|
max_tokens: 1024,
|
|
temperature: 0.2,
|
|
top_p: 0.95,
|
|
top_k: 40,
|
|
frequency_penalty: 0.0,
|
|
presence_penalty: 0.0,
|
|
stop_sequences: vec!["```".to_string()],
|
|
seed: Some(123),
|
|
stream: false,
|
|
}
|
|
}
|
|
|
|
/// Long-form content generation request.
|
|
#[must_use]
|
|
pub fn long_generation_request() -> InferenceRequest {
|
|
InferenceRequest {
|
|
prompt: "Write a detailed technical blog post about distributed systems:".to_string(),
|
|
max_tokens: 4096,
|
|
temperature: 0.8,
|
|
top_p: 0.9,
|
|
top_k: 100,
|
|
frequency_penalty: 0.3,
|
|
presence_penalty: 0.3,
|
|
stop_sequences: vec![],
|
|
seed: None,
|
|
stream: true,
|
|
}
|
|
}
|
|
|
|
/// Summarization request.
|
|
#[must_use]
|
|
pub fn summarization_request() -> InferenceRequest {
|
|
InferenceRequest {
|
|
prompt: "Summarize the following article in 3 bullet points:\n\n[Article text would go here]\n\nSummary:".to_string(),
|
|
max_tokens: 256,
|
|
temperature: 0.3,
|
|
top_p: 0.9,
|
|
top_k: 20,
|
|
frequency_penalty: 0.0,
|
|
presence_penalty: 0.0,
|
|
stop_sequences: vec!["\n\n".to_string()],
|
|
seed: Some(456),
|
|
stream: false,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Generation Configurations
|
|
// ============================================================================
|
|
|
|
/// Creative generation configuration.
|
|
#[must_use]
|
|
pub fn creative_generation_config() -> GenerationConfig {
|
|
GenerationConfig {
|
|
max_new_tokens: 1024,
|
|
min_new_tokens: 50,
|
|
do_sample: true,
|
|
sampling: SamplingParams {
|
|
temperature: 0.9,
|
|
top_p: 0.95,
|
|
top_k: 100,
|
|
typical_p: 0.95,
|
|
eta_cutoff: 0.0,
|
|
epsilon_cutoff: 0.0,
|
|
},
|
|
num_beams: 1,
|
|
early_stopping: false,
|
|
repetition_penalty: 1.1,
|
|
length_penalty: 1.0,
|
|
num_return_sequences: 1,
|
|
}
|
|
}
|
|
|
|
/// Precise generation configuration.
|
|
#[must_use]
|
|
pub fn precise_generation_config() -> GenerationConfig {
|
|
GenerationConfig {
|
|
max_new_tokens: 512,
|
|
min_new_tokens: 1,
|
|
do_sample: false,
|
|
sampling: SamplingParams {
|
|
temperature: 0.0,
|
|
top_p: 1.0,
|
|
top_k: 1,
|
|
typical_p: 1.0,
|
|
eta_cutoff: 0.0,
|
|
epsilon_cutoff: 0.0,
|
|
},
|
|
num_beams: 4,
|
|
early_stopping: true,
|
|
repetition_penalty: 1.0,
|
|
length_penalty: 0.8,
|
|
num_return_sequences: 1,
|
|
}
|
|
}
|
|
|
|
/// Balanced generation configuration.
|
|
#[must_use]
|
|
pub fn balanced_generation_config() -> GenerationConfig {
|
|
GenerationConfig {
|
|
max_new_tokens: 512,
|
|
min_new_tokens: 10,
|
|
do_sample: true,
|
|
sampling: SamplingParams {
|
|
temperature: 0.7,
|
|
top_p: 0.9,
|
|
top_k: 50,
|
|
typical_p: 1.0,
|
|
eta_cutoff: 0.0,
|
|
epsilon_cutoff: 0.0,
|
|
},
|
|
num_beams: 1,
|
|
early_stopping: false,
|
|
repetition_penalty: 1.0,
|
|
length_penalty: 1.0,
|
|
num_return_sequences: 1,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// KV Cache Configurations
|
|
// ============================================================================
|
|
|
|
/// KV cache for LLaMA 70B.
|
|
#[must_use]
|
|
pub fn llama_70b_kv_cache() -> KVCacheConfig {
|
|
KVCacheConfig {
|
|
max_seq_len: 4096,
|
|
max_batch_size: 1,
|
|
num_layers: 80,
|
|
num_kv_heads: 8,
|
|
head_dim: 128,
|
|
dtype: DataType::BFloat16,
|
|
paged_attention: true,
|
|
block_size: 16,
|
|
}
|
|
}
|
|
|
|
/// KV cache for LLaMA 405B.
|
|
#[must_use]
|
|
pub fn llama_405b_kv_cache() -> KVCacheConfig {
|
|
KVCacheConfig {
|
|
max_seq_len: 8192,
|
|
max_batch_size: 1,
|
|
num_layers: 126,
|
|
num_kv_heads: 8,
|
|
head_dim: 128,
|
|
dtype: DataType::BFloat16,
|
|
paged_attention: true,
|
|
block_size: 32,
|
|
}
|
|
}
|
|
|
|
/// KV cache for long context.
|
|
#[must_use]
|
|
pub fn long_context_kv_cache() -> KVCacheConfig {
|
|
KVCacheConfig {
|
|
max_seq_len: 131072,
|
|
max_batch_size: 1,
|
|
num_layers: 126,
|
|
num_kv_heads: 8,
|
|
head_dim: 128,
|
|
dtype: DataType::FP8, // Use FP8 for memory efficiency
|
|
paged_attention: true,
|
|
block_size: 64,
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Benchmark Configurations
|
|
// ============================================================================
|
|
|
|
/// Configuration for throughput benchmarking.
|
|
#[derive(Debug, Clone)]
|
|
pub struct BenchmarkConfig {
|
|
/// Number of warmup iterations.
|
|
pub warmup_iters: usize,
|
|
/// Number of benchmark iterations.
|
|
pub bench_iters: usize,
|
|
/// Prompt lengths to test.
|
|
pub prompt_lengths: Vec<usize>,
|
|
/// Generation lengths to test.
|
|
pub gen_lengths: Vec<usize>,
|
|
/// Batch sizes to test.
|
|
pub batch_sizes: Vec<usize>,
|
|
}
|
|
|
|
impl Default for BenchmarkConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
warmup_iters: 3,
|
|
bench_iters: 10,
|
|
prompt_lengths: vec![128, 512, 1024, 2048],
|
|
gen_lengths: vec![64, 128, 256, 512],
|
|
batch_sizes: vec![1],
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Throughput benchmark configuration.
|
|
#[must_use]
|
|
pub fn throughput_benchmark() -> BenchmarkConfig {
|
|
BenchmarkConfig {
|
|
warmup_iters: 5,
|
|
bench_iters: 20,
|
|
prompt_lengths: vec![128, 512, 2048],
|
|
gen_lengths: vec![128, 512],
|
|
batch_sizes: vec![1, 2, 4],
|
|
}
|
|
}
|
|
|
|
/// Latency benchmark configuration.
|
|
#[must_use]
|
|
pub fn latency_benchmark() -> BenchmarkConfig {
|
|
BenchmarkConfig {
|
|
warmup_iters: 10,
|
|
bench_iters: 50,
|
|
prompt_lengths: vec![64, 256, 1024],
|
|
gen_lengths: vec![1, 32, 128],
|
|
batch_sizes: vec![1],
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Tests
|
|
// ============================================================================
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_llama_7b_config() {
|
|
let config = llama_7b_config();
|
|
assert_eq!(config.num_layers, 32);
|
|
assert_eq!(config.num_heads, 32);
|
|
}
|
|
|
|
#[test]
|
|
fn test_llama_70b_config() {
|
|
let config = llama_70b_config();
|
|
assert_eq!(config.num_layers, 80);
|
|
assert_eq!(config.num_kv_heads, 8); // GQA
|
|
}
|
|
|
|
#[test]
|
|
fn test_llama_405b_config() {
|
|
let config = llama_405b_config();
|
|
assert_eq!(config.num_layers, 126);
|
|
assert!(config.num_params > 400.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_four_node_cluster() {
|
|
let cluster = four_node_cluster();
|
|
assert_eq!(cluster.nodes.len(), 4);
|
|
assert!((cluster.total_memory_gb - 768.0).abs() < 1.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_eight_node_cluster() {
|
|
let cluster = eight_node_cluster();
|
|
assert_eq!(cluster.nodes.len(), 8);
|
|
assert_eq!(cluster.topology, NetworkTopology::Mesh);
|
|
}
|
|
|
|
#[test]
|
|
fn test_parallel_configs() {
|
|
let single = single_node_parallel_config();
|
|
assert_eq!(single.world_size, 1);
|
|
|
|
let four = four_node_parallel_config();
|
|
assert_eq!(four.pipeline_parallel, 4);
|
|
|
|
let hybrid = four_node_hybrid_config();
|
|
assert_eq!(
|
|
hybrid.tensor_parallel * hybrid.pipeline_parallel,
|
|
hybrid.world_size
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_inference_requests() {
|
|
let chat = chat_inference_request();
|
|
assert!(chat.stream);
|
|
assert!(!chat.stop_sequences.is_empty());
|
|
|
|
let code = code_completion_request();
|
|
assert!(code.temperature < 0.5);
|
|
}
|
|
|
|
#[test]
|
|
fn test_generation_configs() {
|
|
let creative = creative_generation_config();
|
|
assert!(creative.sampling.temperature > 0.8);
|
|
assert!(creative.do_sample);
|
|
|
|
let precise = precise_generation_config();
|
|
assert!(!precise.do_sample);
|
|
assert!(precise.num_beams > 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_kv_cache_configs() {
|
|
let cache_70b = llama_70b_kv_cache();
|
|
assert_eq!(cache_70b.num_layers, 80);
|
|
assert!(cache_70b.paged_attention);
|
|
|
|
let cache_405b = llama_405b_kv_cache();
|
|
assert_eq!(cache_405b.num_layers, 126);
|
|
}
|
|
|
|
#[test]
|
|
fn test_benchmark_configs() {
|
|
let throughput = throughput_benchmark();
|
|
assert!(throughput.bench_iters > throughput.warmup_iters);
|
|
|
|
let latency = latency_benchmark();
|
|
assert!(!latency.gen_lengths.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn test_model_memory_estimates() {
|
|
let llama_70b = llama_70b_config();
|
|
let mem = llama_70b.estimated_memory_gb();
|
|
// 70B * 2 bytes = 140 GB
|
|
assert!((mem - 140.0).abs() < 5.0);
|
|
|
|
let llama_405b = llama_405b_config();
|
|
let mem_405b = llama_405b.estimated_memory_gb();
|
|
// 405B * 2 bytes = 810 GB
|
|
assert!((mem_405b - 810.0).abs() < 10.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_cluster_bandwidth() {
|
|
let cluster = four_node_cluster();
|
|
for node in &cluster.nodes {
|
|
assert_eq!(node.network.bandwidth_gbps(), 80.0);
|
|
}
|
|
}
|
|
}
|