char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
e2eb39e81
char/aliceai-t5-moe
1#!/usr/bin/env python3 2 3import numpy as np 4import sys 5import os 6import argparse 7from pathlib import Path 8from common import get_model_name_from_env_path # type: ignore[import-not-found, ty:unresolved-import] 9 10def calculate_nmse (reference ,test ): 11mse = np .mean ((test - reference )** 2 ) 12ref_var = np .var (reference ) 13if ref_var == 0 : 14nmse = float ('inf' )if mse > 0 else 0.0 15return mse ,mse ,ref_var 16 17nmse = mse / ref_var 18 19return nmse ,mse ,ref_var 20 21def load_logits (file_path ): 22if not os .path .exists (file_path ): 23raise FileNotFoundError (f"File not found: { file_path } " ) 24 25if file_path .suffix == '.npy' : 26return np .load (file_path ) 27elif file_path .suffix == '.bin' : 28return np .fromfile (file_path ,dtype = np .float32 ) 29else : 30# Try to load as text file 31try : 32# If it has index format "0: value", extract just values 33data = [] 34with open (file_path ,'r' )as f : 35for line in f : 36if ':' in line : 37# Format: "index: value" 38value = float (line .split (':' )[1 ].strip ()) 39else : 40# Just the value 41value = float (line .strip ()) 42data .append (value ) 43return np .array (data ,dtype = np .float32 ) 44except : 45return np .loadtxt (file_path ,dtype = np .float32 ) 46 47def interpret_nmse (nmse ): 48"""Provide interpretation of NMSE value""" 49if nmse == 0 : 50return "Perfect match" ,"π" 51elif nmse < 1e-6 : 52return "Essentially identical" ,"β " 53elif nmse < 1e-4 : 54return "Excellent match" ,"β " 55elif nmse < 1e-3 : 56return "Very good match" ,"π" 57elif nmse < 1e-2 : 58return "Good match" ,"π" 59elif nmse < 0.1 : 60return "Acceptable match" ,"β οΈ" 61elif nmse < 1.0 : 62return "Poor match" ,"β" 63else : 64return "Very poor match (worse than noise)" ,"β" 65 66def main (): 67parser = argparse .ArgumentParser (description = 'Validate model logits' ) 68parser .add_argument ('-m' ,'--model-path' ,required = True ,help = 'Path to the model directory' ) 69args = parser .parse_args () 70 71model_name = get_model_name_from_env_path ('MODEL_PATH' ) 72data_dir = Path ("data" ) 73 74pytorch_file = data_dir / f"pytorch- { model_name } .bin" 75 76llamacpp_model_name = get_model_name_from_env_path ('CONVERTED_MODEL' ) 77llamacpp_file = data_dir / f"llamacpp- { llamacpp_model_name } .bin" 78 79f"Model name: { model_name } " ) 80f"PyTorch logits file: { pytorch_file } " ) 81f"llama.cpp logits file: { llamacpp_file } " ) 82 83reference_file = pytorch_file 84test_file = llamacpp_file 85 86"π NMSE Check for Model Comparison" ) 87"=" * 50 ) 88f"Reference (ground truth): { reference_file } " ) 89f"Test (to evaluate): { test_file } " ) 90try : 93"Loading reference logits..." ) 94reference = load_logits (reference_file ) 95f" Shape: { reference . shape } , Type: { reference . dtype } " ) 96 97"Loading test logits..." ) 98test = load_logits (test_file ) 99f" Shape: { test . shape } , Type: { test . dtype } " ) 100 101# Check shapes match 102if reference .shape != test .shape : 103f"\nβ Error: Shape mismatch!" ) 104f" Reference: { reference . shape } " ) 105f" Test: { test . shape } " ) 106sys .exit (1 ) 107 108f"\nβ Shapes match: { reference . shape } " ) 109 110nmse ,mse ,ref_var = calculate_nmse (reference ,test ) 111 112# Additional metrics 113max_abs_error = np .max (np .abs (test - reference )) 114mean_abs_error = np .mean (np .abs (test - reference )) 115 116# Results 117f"\nπ METRICS" ) 118"=" * 30 ) 119f"MSE (Mean Squared Error): { mse :.6e } " ) 120f"Reference Variance: { ref_var :.6e } " ) 121f"NMSE: { nmse :.6e } " ) 122f"Max Absolute Error: { max_abs_error :.6f } " ) 123f"Mean Absolute Error: { mean_abs_error :.6f } " ) 124 125# NMSE in dB (common in signal processing) 126if nmse > 0 : 127nmse_db = 10 * np .log10 (nmse ) 128f"NMSE (dB): { nmse_db :.2f } dB" ) 129 130# Interpretation 131interpretation ,emoji = interpret_nmse (nmse ) 132f"\nπ― INTERPRETATION" ) 133"=" * 30 ) 134f" { emoji } { interpretation } " ) 135 136# Detailed guidance 137f"\nπ GUIDANCE" ) 138"=" * 30 ) 139if nmse < 1e-3 : 140"β EXCELLENT: Your GGML conversion is working very well!" ) 141" The differences are negligible for practical use." ) 142elif nmse < 1e-2 : 143"π GOOD: Your GGML conversion is working well." ) 144" Small differences are likely due to precision/quantization." ) 145elif nmse < 0.1 : 146"β οΈ ACCEPTABLE: Conversion is working but with some differences." ) 147" Check if you're using quantization (Q4, Q8, etc.)" ) 148" Test generation quality to see if it's acceptable." ) 149else : 150"β PROBLEMATIC: Large differences detected." ) 151" Check your conversion process for potential issues." ) 152" Verify you're using the same model weights." ) 153 154# NMSE benchmarks 155f"\nπ NMSE BENCHMARKS" ) 156"=" * 30 ) 157"< 1e-6: Essentially identical" ) 158"< 1e-4: Excellent (typical for good conversions)" ) 159"< 1e-3: Very good" ) 160"< 1e-2: Good (acceptable for most use cases)" ) 161"< 0.1: Acceptable (may need verification)" ) 162"> 1.0: Poor (worse than random)" ) 163 164# Exit code based on NMSE 165if nmse < 1e-2 : 166f"\nβ RESULT: PASS (NMSE = { nmse :.2e } )" ) 167sys .exit (0 ) 168else : 169f"\nβ RESULT: NEEDS REVIEW (NMSE = { nmse :.2e } )" ) 170sys .exit (1 ) 171 172except Exception as e : 173f"β Error: { e } " ) 174sys .exit (1 ) 175 176if __name__ == "__main__" : 177main ()