/home/noah/src/realizar/src/api/test_helpers.rs
Line | Count | Source |
1 | | //! Test helper functions for api tests |
2 | | //! |
3 | | //! This module contains shared test utilities used across multiple test parts. |
4 | | //! Separated for PMAT compliance (<2000 lines per file). |
5 | | |
6 | | use super::*; |
7 | | use axum::Router; |
8 | | |
9 | | /// Create a test application with demo state |
10 | 84 | pub fn create_test_app() -> Router { |
11 | 84 | let state = AppState::demo().expect("test"); |
12 | 84 | create_router(state) |
13 | 84 | } |
14 | | |
15 | | /// Helper to create test quantized model for IMP-116 tests |
16 | | #[cfg(feature = "gpu")] |
17 | 27 | pub fn create_test_quantized_model( |
18 | 27 | config: &crate::gguf::GGUFConfig, |
19 | 27 | ) -> crate::gguf::OwnedQuantizedModel { |
20 | | use crate::gguf::{ |
21 | | OwnedQKVWeights, OwnedQuantizedLayer, OwnedQuantizedModel, OwnedQuantizedTensor, |
22 | | GGUF_TYPE_Q4_K, |
23 | | }; |
24 | | |
25 | 27 | let hidden_dim = config.hidden_dim; |
26 | 27 | let intermediate_dim = config.intermediate_dim; |
27 | 27 | let vocab_size = config.vocab_size; |
28 | | |
29 | | // Create Q4_K tensor data helper |
30 | | // Q4_K uses row-major storage where each row has ceil(in_dim/256) super-blocks. |
31 | | // Each super-block is 144 bytes and covers 256 values. |
32 | 139 | fn create_q4k_data(in_dim: usize, out_dim: usize) -> OwnedQuantizedTensor { |
33 | 139 | let super_blocks_per_row = in_dim.div_ceil(256); |
34 | 139 | let bytes_per_row = super_blocks_per_row * 144; |
35 | 139 | let data_size = out_dim * bytes_per_row; |
36 | 139 | OwnedQuantizedTensor { |
37 | 139 | data: vec![0u8; data_size], |
38 | 139 | qtype: GGUF_TYPE_Q4_K, |
39 | 139 | in_dim, |
40 | 139 | out_dim, |
41 | 139 | } |
42 | 139 | } |
43 | | |
44 | 27 | let layers = (0..config.num_layers) |
45 | 27 | .map(|_| OwnedQuantizedLayer { |
46 | 28 | attn_norm_weight: vec![1.0f32; hidden_dim], |
47 | 28 | attn_norm_bias: None, |
48 | 28 | qkv_weight: OwnedQKVWeights::Fused(create_q4k_data(hidden_dim, hidden_dim * 3)), |
49 | 28 | qkv_bias: None, |
50 | 28 | attn_output_weight: create_q4k_data(hidden_dim, hidden_dim), |
51 | 28 | attn_output_bias: None, |
52 | 28 | ffn_up_weight: create_q4k_data(hidden_dim, intermediate_dim), |
53 | 28 | ffn_up_bias: None, |
54 | 28 | ffn_down_weight: create_q4k_data(intermediate_dim, hidden_dim), |
55 | 28 | ffn_down_bias: None, |
56 | 28 | ffn_gate_weight: None, |
57 | 28 | ffn_gate_bias: None, |
58 | 28 | ffn_norm_weight: None, |
59 | 28 | ffn_norm_bias: None, |
60 | 28 | }) |
61 | 27 | .collect(); |
62 | | |
63 | 27 | OwnedQuantizedModel { |
64 | 27 | config: config.clone(), |
65 | 27 | token_embedding: vec![0.1f32; vocab_size * hidden_dim], |
66 | 27 | layers, |
67 | 27 | output_norm_weight: vec![1.0f32; hidden_dim], |
68 | 27 | output_norm_bias: None, |
69 | 27 | lm_head_weight: create_q4k_data(hidden_dim, vocab_size), |
70 | 27 | lm_head_bias: None, |
71 | 27 | #[cfg(feature = "cuda")] |
72 | 27 | cuda_executor: None, |
73 | 27 | #[cfg(feature = "cuda")] |
74 | 27 | cuda_kernel_count: std::sync::atomic::AtomicU64::new(0), |
75 | 27 | #[cfg(feature = "cuda")] |
76 | 27 | cached_weight_names: std::sync::Mutex::new(std::collections::HashSet::new()), |
77 | 27 | } |
78 | 27 | } |