#[cfg(test)]
#[allow(clippy::module_inception)]
mod tests {
use crate::gpt_neox::config::GPTNeoXConfig;
use crate::gpt_neox::model::{GPTNeoXForCausalLM, GPTNeoXModel};
use trustformers_core::traits::{Config, Model};
#[test]
fn test_gpt_neox_config_validation() {
let config = GPTNeoXConfig {
vocab_size: 1000,
hidden_size: 64,
num_hidden_layers: 2,
num_attention_heads: 8,
intermediate_size: 256,
max_position_embeddings: 512,
layer_norm_eps: 1e-5,
hidden_act: "gelu".to_string(),
rotary_emb_base: 10000.0,
rotary_pct: 1.0,
use_parallel_residual: false,
tie_word_embeddings: false,
initializer_range: 0.02,
bos_token_id: Some(0),
eos_token_id: Some(2),
};
assert!(config.validate().is_ok());
assert_eq!(config.hidden_size / config.num_attention_heads, 8);
drop(config);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_config_with_parallel_residual() {
let config = GPTNeoXConfig {
vocab_size: 1000,
hidden_size: 64,
num_hidden_layers: 2,
num_attention_heads: 8,
intermediate_size: 256,
max_position_embeddings: 512,
use_parallel_residual: true, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_ok());
assert!(config.use_parallel_residual);
drop(config);
std::hint::black_box(());
}
#[test]
fn test_rinna_japanese_config() {
let config = GPTNeoXConfig::rinna_japanese_3_6b();
assert!(config.validate().is_ok());
assert_eq!(config.vocab_size, 32000);
assert_eq!(config.hidden_size, 2816);
assert_eq!(config.num_hidden_layers, 36);
assert_eq!(config.num_attention_heads, 22);
assert_eq!(config.intermediate_size, 11264);
drop(config);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_architecture() {
let config = GPTNeoXConfig::default();
assert_eq!(config.architecture(), "gpt_neox");
}
#[test]
fn test_invalid_gpt_neox_config() {
let config = GPTNeoXConfig {
hidden_size: 65, num_attention_heads: 8,
..GPTNeoXConfig::default()
};
assert!(config.validate().is_err());
}
#[test]
fn test_invalid_rotary_pct() {
let config = GPTNeoXConfig {
rotary_pct: 1.5, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_err());
}
#[test]
fn test_gpt_neox_model_creation() {
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 32,
num_hidden_layers: 2,
num_attention_heads: 4,
intermediate_size: 128,
max_position_embeddings: 64,
..GPTNeoXConfig::default()
};
let model = GPTNeoXModel::new(config.clone()).expect("operation failed");
assert_eq!(model.get_config().num_hidden_layers, 2);
assert_eq!(model.get_config().hidden_size, 32);
assert_eq!(model.get_config().num_attention_heads, 4);
drop(model);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_for_causal_lm_creation() {
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 32,
num_hidden_layers: 2,
num_attention_heads: 4,
intermediate_size: 128,
max_position_embeddings: 64,
..GPTNeoXConfig::default()
};
let model = GPTNeoXForCausalLM::new(config.clone()).expect("operation failed");
assert_eq!(model.get_config().num_hidden_layers, 2);
assert_eq!(model.get_config().vocab_size, 100);
drop(model);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_forward_pass() {
use trustformers_core::tensor::Tensor;
use trustformers_core::traits::Model;
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 32,
num_hidden_layers: 2,
num_attention_heads: 4,
intermediate_size: 128,
max_position_embeddings: 64,
..GPTNeoXConfig::default()
};
let model = GPTNeoXModel::new(config).expect("operation failed");
let input_ids = vec![1, 2, 3, 4, 5];
let output = model.forward(input_ids.clone()).expect("operation failed");
match &output {
Tensor::F32(arr) => {
assert_eq!(arr.shape().len(), 2);
assert_eq!(arr.shape()[0], input_ids.len());
assert_eq!(arr.shape()[1], 32);
},
_ => panic!("Expected F32 tensor"),
}
drop(model);
drop(output);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_parameter_count() {
use trustformers_core::traits::Model;
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 32,
num_hidden_layers: 2,
num_attention_heads: 4,
intermediate_size: 128,
max_position_embeddings: 64,
..GPTNeoXConfig::default()
};
let model = GPTNeoXModel::new(config).expect("operation failed");
let param_count = model.num_parameters();
assert!(param_count > 0);
println!("GPT-NeoX model parameter count: {}", param_count);
drop(model);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_config_default_values() {
let config = GPTNeoXConfig::default();
assert_eq!(config.vocab_size, 50432);
assert_eq!(config.hidden_size, 2048);
assert_eq!(config.num_hidden_layers, 16);
assert_eq!(config.num_attention_heads, 16);
assert_eq!(config.intermediate_size, 8192);
assert_eq!(config.max_position_embeddings, 2048);
assert_eq!(config.layer_norm_eps, 1e-5);
assert_eq!(config.hidden_act, "gelu");
assert_eq!(config.rotary_emb_base, 10000.0);
assert_eq!(config.rotary_pct, 1.0);
assert!(!config.use_parallel_residual);
assert!(!config.tie_word_embeddings);
assert_eq!(config.bos_token_id, Some(0));
assert_eq!(config.eos_token_id, Some(2));
drop(config);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_variable_sequence_lengths() {
use trustformers_core::tensor::Tensor;
use trustformers_core::traits::Model;
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 32,
num_hidden_layers: 1, num_attention_heads: 4,
intermediate_size: 64, max_position_embeddings: 32, ..GPTNeoXConfig::default()
};
let model = GPTNeoXModel::new(config).expect("operation failed");
for seq_len in [1, 3, 5] {
let input_ids: Vec<u32> = (0..seq_len).map(|i| (i % 100) as u32).collect();
let output = model
.forward(input_ids.clone())
.unwrap_or_else(|_| panic!("Forward pass failed for seq_len={}", seq_len));
match &output {
Tensor::F32(arr) => {
assert_eq!(arr.shape()[0], seq_len);
assert_eq!(arr.shape()[1], 32);
},
_ => panic!("Expected F32 tensor"),
}
drop(output);
std::hint::black_box(());
}
drop(model);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_rotary_embedding_coverage() {
let config = GPTNeoXConfig {
vocab_size: 100,
hidden_size: 64,
num_hidden_layers: 2,
num_attention_heads: 8,
intermediate_size: 256,
max_position_embeddings: 128,
rotary_pct: 0.5, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_ok());
let model = GPTNeoXModel::new(config).expect("operation failed");
drop(model);
std::hint::black_box(());
}
#[test]
fn test_gpt_neox_zero_config_fails() {
let config = GPTNeoXConfig {
hidden_size: 0, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_err());
let config = GPTNeoXConfig {
num_hidden_layers: 0, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_err());
let config = GPTNeoXConfig {
num_attention_heads: 0, ..GPTNeoXConfig::default()
};
assert!(config.validate().is_err());
}
}