char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
5594d1322
char/aliceai-t5-moe
1#include "debug.h" 2 3#include "common.h" 4#include "log.h" 5 6#include <cmath> 7#include <regex> 8#include <string> 9#include <vector> 10 11struct common_debug_cb_user_data::impl { 12 std::vector < uint8_t > data ; 13 std::vector < std::regex > tensor_filters ; 14bool abort_on_nan {false}; 15}; 16 17common_debug_cb_user_data::common_debug_cb_user_data () :pimpl (std::make_unique < impl > ()) {} 18common_debug_cb_user_data::~common_debug_cb_user_data ()= default ; 19 20common_debug_cb_user_data::common_debug_cb_user_data (common_params & params ,const std::vector < std::string > & filter_patterns ,bool abort_on_nan ) 21 :pimpl (std::make_unique < impl > ()) 22{ 23for (const auto & pattern :filter_patterns ) { 24try { 25 std::string anchored_pattern = "^" + pattern ; 26pimpl -> tensor_filters .emplace_back (anchored_pattern , std::regex::optimize ); 27 }catch (const std::regex_error & e ) { 28throw std::runtime_error ("Invalid regex pattern '" + pattern + "': " + e .what ()); 29 } 30 } 31pimpl -> abort_on_nan = abort_on_nan ; 32 33params .cb_eval = common_debug_cb_eval ; 34params .cb_eval_user_data = this ; 35} 36 37static std::string common_ggml_ne_string (const ggml_tensor * t ) { 38 std::string str ; 39for (int i = 0 ;i < GGML_MAX_DIMS ;++ i ) { 40str += std::to_string (t -> ne [i ]); 41if (i + 1 < GGML_MAX_DIMS ) { 42str += ", " ; 43 } 44 } 45return str ; 46} 47 48static float common_ggml_get_float_value (const uint8_t * data , 49ggml_type type , 50const size_t * nb , 51size_t i0 , 52size_t i1 , 53size_t i2 , 54size_t i3 ) { 55size_t i = i3 * nb [3 ]+ i2 * nb [2 ]+ i1 * nb [1 ]+ i0 * nb [0 ]; 56float v ; 57if (type == GGML_TYPE_F16 ) { 58v = ggml_fp16_to_fp32 (* (const ggml_fp16_t * )& data [i ]); 59 }else if (type == GGML_TYPE_F32 ) { 60v = * (const float * )& data [i ]; 61 }else if (type == GGML_TYPE_I64 ) { 62v = (float )* (const int64_t * )& data [i ]; 63 }else if (type == GGML_TYPE_I32 ) { 64v = (float )* (const int32_t * )& data [i ]; 65 }else if (type == GGML_TYPE_I16 ) { 66v = (float )* (const int16_t * )& data [i ]; 67 }else if (type == GGML_TYPE_I8 ) { 68v = (float )* (const int8_t * )& data [i ]; 69 }else if (type == GGML_TYPE_BF16 ) { 70v = ggml_bf16_to_fp32 (* (const ggml_bf16_t * )& data [i ]); 71 }else { 72GGML_ABORT ("fatal error" ); 73 } 74return v ; 75} 76 77#define INDENT " " 78 79static void common_debug_print_tensor (uint8_t * data ,ggml_type type ,const int64_t * ne ,const size_t * nb ,int64_t n ,bool abort_on_nan ) { 80GGML_ASSERT (n > 0 ); 81float sum = 0 ; 82for (int64_t i3 = 0 ;i3 < ne [3 ];i3 ++ ) { 83for (int64_t i2 = 0 ;i2 < ne [2 ];i2 ++ ) { 84for (int64_t i1 = 0 ;i1 < ne [1 ];i1 ++ ) { 85for (int64_t i0 = 0 ;i0 < ne [0 ];i0 ++ ) { 86const float v = common_ggml_get_float_value (data ,type ,nb ,i0 ,i1 ,i2 ,i3 ); 87sum += v ; 88 } 89 } 90 } 91 } 92for (int64_t i3 = 0 ;i3 < ne [3 ];i3 ++ ) { 93LOG (INDENT "[\n" ); 94for (int64_t i2 = 0 ;i2 < ne [2 ];i2 ++ ) { 95if (i2 == n && ne [2 ]> 2 * n ) { 96LOG (INDENT INDENT "..., \n" ); 97i2 = ne [2 ]- n ; 98 } 99LOG (INDENT INDENT "[\n" ); 100for (int64_t i1 = 0 ;i1 < ne [1 ];i1 ++ ) { 101if (i1 == n && ne [1 ]> 2 * n ) { 102LOG (INDENT INDENT INDENT "..., \n" ); 103i1 = ne [1 ]- n ; 104 } 105LOG (INDENT INDENT INDENT "["); 106for (int64_t i0 = 0 ;i0 < ne [0 ];i0 ++ ) { 107if (i0 == n && ne [0 ]> 2 * n ) { 108LOG (" ..., " ); 109i0 = ne [0 ]- n ; 110 } 111const float v = common_ggml_get_float_value (data ,type ,nb ,i0 ,i1 ,i2 ,i3 ); 112LOG ("%12.4f" ,v ); 113if (i0 < ne [0 ]- 1 ) { 114LOG (", " ); 115 } 116 } 117LOG (" ],\n" ); 118 } 119LOG (INDENT INDENT "],\n" ); 120 } 121LOG (INDENT "]\n" ); 122LOG (INDENT "sum = %f\n" ,sum ); 123 } 124 125if (abort_on_nan ) { 126if (std::isnan (sum )) { 127LOG ("encountered NaN - aborting\n" ); 128exit (0 ); 129 } 130 } 131} 132 133/** 134* GGML operations callback during the graph execution. 135* 136* @param t current tensor 137* @param ask when ask is true, the scheduler wants to know if we are interested in data from this tensor 138* if we return true, a follow-up call will be made with ask=false in which we can do the actual collection. 139* see ggml_backend_sched_eval_callback 140* @param user_data user data to pass at each call back 141* @return true to receive data or continue the graph, false otherwise 142*/ 143bool common_debug_cb_eval (struct ggml_tensor * t ,bool ask ,void * user_data ) { 144auto * cb_data = (common_debug_cb_user_data * )user_data ; 145auto * pimpl = cb_data -> pimpl .get (); 146 147const struct ggml_tensor * src0 = t -> src [0 ]; 148const struct ggml_tensor * src1 = t -> src [1 ]; 149 150if (ask ) { 151return true;// Always retrieve data 152 } 153 154bool matches_filter = pimpl -> tensor_filters .empty (); 155 156if (!matches_filter ) { 157for (const auto & filter :pimpl -> tensor_filters ) { 158if (std::regex_search (t -> name ,filter )) { 159matches_filter = true; 160break ; 161 } 162 } 163 } 164 165char src1_str [128 ]= {0 }; 166if (src1 ) { 167snprintf (src1_str ,sizeof (src1_str ),"%s{%s}" ,src1 -> name ,common_ggml_ne_string (src1 ).c_str ()); 168 } 169 170if (matches_filter ) { 171LOG ("%s: %24s = (%s) %10s(%s{%s}, %s}) = {%s}\n" ,__func__ ,t -> name ,ggml_type_name (t -> type ), 172ggml_op_desc (t ),src0 -> name ,common_ggml_ne_string (src0 ).c_str (),src1 ?src1_str :"" , 173common_ggml_ne_string (t ).c_str ()); 174 } 175 176const bool is_host = ggml_backend_buffer_is_host (t -> buffer ); 177 178if (!is_host ) { 179auto n_bytes = ggml_nbytes (t ); 180pimpl -> data .resize (n_bytes ); 181ggml_backend_tensor_get (t ,pimpl -> data .data (),0 ,n_bytes ); 182 } 183 184if (!ggml_is_quantized (t -> type )&& matches_filter ) { 185uint8_t * data = is_host ? (uint8_t * )t -> data :pimpl -> data .data (); 186common_debug_print_tensor (data ,t -> type ,t -> ne ,t -> nb ,3 ,pimpl -> abort_on_nan ); 187 } 188 189return true; 190}