hf2q 0.1.1

Pure Rust CLI for converting HuggingFace models to hardware-optimized formats and serving them over an OpenAI-compatible API on Apple Silicon
use super::model::Deepseek4Model;
use super::residency_tests::{open_fixture, tiny_config};
use mlx_native::{DType, GgmlType};

#[test]
fn q2_k_embeddings_expand_to_four_identical_hc_streams() {
    let cfg = tiny_config();
    let (_directory, gguf) = open_fixture(&cfg, false, false);
    let _gpu = crate::inference::hf2q_gpu_test_lock();
    let mut model = Deepseek4Model::load_from_gguf(&gguf).unwrap();
    let expected_table = gguf
        .load_tensor_f32("token_embd.weight", model.ctx.device())
        .unwrap();
    let expected = expected_table.as_slice::<f32>().unwrap();

    let actual = model.embed_hyper_state(&[2, 0]).unwrap();
    assert_eq!(actual.shape(), &[2, 4, cfg.hidden_size as usize]);
    let actual = actual.as_slice::<f32>().unwrap();
    let hidden = cfg.hidden_size as usize;
    for (token_slot, token_id) in [2usize, 0].into_iter().enumerate() {
        let expected_row = &expected[token_id * hidden..(token_id + 1) * hidden];
        assert!(expected_row.iter().any(|value| *value != 0.0));
        for lane in 0..4 {
            let offset = (token_slot * 4 + lane) * hidden;
            assert_eq!(&actual[offset..offset + hidden], expected_row);
        }
    }
}

#[test]
fn embedding_forward_rejects_empty_input() {
    let cfg = tiny_config();
    let (_directory, gguf) = open_fixture(&cfg, false, false);
    let _gpu = crate::inference::hf2q_gpu_test_lock();
    let mut model = Deepseek4Model::load_from_gguf(&gguf).unwrap();
    assert!(model.embed_hyper_state(&[]).is_err());
}

#[test]
fn q8_0_embeddings_expand_to_four_identical_hc_streams() {
    const BLOCK_VALUES: usize = 32;
    const BLOCK_BYTES: usize = 34;

    let cfg = tiny_config();
    let (_directory, gguf) = open_fixture(&cfg, false, false);
    let _gpu = crate::inference::hf2q_gpu_test_lock();
    let mut model = Deepseek4Model::load_from_gguf(&gguf).unwrap();
    let vocab = cfg.vocab_size as usize;
    let hidden = cfg.hidden_size as usize;
    let blocks_per_row = hidden / BLOCK_VALUES;
    let mut bytes = vec![0u8; vocab * blocks_per_row * BLOCK_BYTES];
    for row in 0..vocab {
        for block in 0..blocks_per_row {
            let offset = (row * blocks_per_row + block) * BLOCK_BYTES;
            bytes[offset..offset + 2].copy_from_slice(&0x3c00u16.to_le_bytes());
            for column in 0..BLOCK_VALUES {
                bytes[offset + 2 + column] =
                    ((row as i16 + block as i16 + column as i16) % 31 - 15) as i8 as u8;
            }
        }
    }
    let mut weight = model
        .ctx
        .device()
        .alloc_buffer(bytes.len(), DType::U8, vec![vocab, hidden])
        .unwrap();
    weight.as_mut_slice::<u8>().unwrap().copy_from_slice(&bytes);
    let arena = model.prepare_embedding_arena(&[2, 0]).unwrap();
    let (executor, registry) = model.ctx.split();
    let mut session = executor.begin().unwrap();
    Deepseek4Model::encode_embedding_hyper_state(
        &mut session,
        registry,
        executor.device(),
        &weight,
        GgmlType::Q8_0,
        &[vocab, hidden],
        &arena,
        2,
        vocab,
        hidden,
        cfg.hyper_connection_count,
    )
    .unwrap();
    session.finish().unwrap();

    let actual = arena.state.as_slice::<f32>().unwrap();
    for (token_slot, token_id) in [2usize, 0].into_iter().enumerate() {
        for lane in 0..cfg.hyper_connection_count as usize {
            let offset = (token_slot * cfg.hyper_connection_count as usize + lane) * hidden;
            for column in 0..hidden {
                let expected =
                    ((token_id + column / BLOCK_VALUES + column % BLOCK_VALUES) % 31) as i32 - 15;
                assert_eq!(actual[offset + column], expected as f32);
            }
        }
    }
}