char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
d8794eecd
char/aliceai-t5-moe
1#include "diffusion.h" 2 3#include "log.h" 4 5#include <algorithm> 6#include <cstddef> 7#include <cmath> 8#include <cstring> 9#include <random> 10#include <utility> 11#include <vector> 12 13static float calculate_confidence (const llama_token_data_array & cur_p , 14diffusion_algorithm algorithm , 15 std::mt19937 & rng ) { 16switch (algorithm ) { 17case DIFFUSION_ALGORITHM_CONFIDENCE_BASED : 18return cur_p .data [cur_p .selected ].p ;// Selected token probability 19 20case DIFFUSION_ALGORITHM_ENTROPY_BASED : 21 { 22float entropy = 0.0f ; 23const float epsilon = 1e-10f ; 24for (size_t i = 0 ;i < cur_p .size ;i ++ ) { 25float prob = cur_p .data [i ].p ; 26entropy += prob * logf (prob + epsilon ); 27 } 28return - entropy ;// Higher entropy = lower confidence 29 } 30 31case DIFFUSION_ALGORITHM_MARGIN_BASED : 32return (cur_p .size > 1 ) ?cur_p .data [0 ].p - cur_p .data [1 ].p :cur_p .data [0 ].p ; 33 34case DIFFUSION_ALGORITHM_RANDOM : 35 { 36 std::uniform_real_distribution < float > uniform (0.0f ,1.0f ); 37return uniform (rng );// Random confidence 38 } 39 40case DIFFUSION_ALGORITHM_ORIGIN : 41return cur_p .data [cur_p .selected ].p ; 42 43default : 44return 0.0f ; 45 } 46} 47 48// Unified transfer count calculation function 49static int32_t calculate_transfer_count (int32_t step , 50int32_t total_steps , 51int32_t remaining_masked , 52diffusion_transfer_schedule schedule , 53float eps , 54const std::vector < int32_t > & num_transfer_tokens = {}) { 55switch ( schedule ) { 56case DIFFUSION_TRANSFER_SCHEDULE_TIMESTEP_BASED : 57{ 58float t = 1.0f - (float) step / total_steps * ( 1.0f - eps ); 59float s = 1.0f - (float) ( step + 1 ) / total_steps * ( 1.0f - eps ); 60float p_transfer = ( step < total_steps - 1 ) ? ( 1.0f - s / t ) : 1.0f ; 61return (int32_t) ( remaining_masked * p_transfer ); 62} 63 64case DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED : 65if (! num_transfer_tokens . empty () && step < (int32_t) num_transfer_tokens . size ()) { 66return num_transfer_tokens [ step ]; 67} 68return remaining_masked / ( total_steps - step ); // Fallback 69 70default : 71return remaining_masked / ( total_steps - step ); 72} 73} 74 75static void add_gumbel_noise (float * logits , int32_t n_vocab , float temperature , std::mt19937 & rng ) { 76if ( temperature == 0.0f ) { 77return ; 78} 79 80std::uniform_real_distribution < double > uniform ( 0.0 , 1.0 ); 81for (int32_t i = 0 ; i < n_vocab ; i ++ ) { 82double noise = uniform ( rng ); 83// Prevent log(0) 84noise = std:: max ( noise , 1e-20 ); 85double gumbel_noise = std:: pow ( - std:: log ( noise ), temperature ); 86logits [ i ] = std:: exp ( logits [ i ]) / gumbel_noise ; 87} 88} 89 90static std::vector < int32_t > get_num_transfer_tokens (int32_t mask_count , int32_t steps ) { 91std::vector < int32_t > num_transfer_tokens (steps); 92 93int32_t base = mask_count / steps ; 94int32_t remainder = mask_count % steps ; 95 96for (int32_t i = 0 ; i < steps ; i ++ ) { 97num_transfer_tokens [ i ] = base + ( i < remainder ? 1 : 0 ); 98} 99 100return num_transfer_tokens ; 101} 102 103void diffusion_generate (llama_context * ctx , 104const llama_token * input_tokens , 105llama_token * output_tokens , 106int32_t n_input , 107const diffusion_params & params , 108int32_t & n_generated ) { 109n_generated = 0 ; 110if (! ctx || ! input_tokens || ! output_tokens || n_input <= 0 || params . max_length <= n_input ) { 111return ; 112} 113 114const llama_model * model = llama_get_model ( ctx ); 115 116// Initialize with input and pad with mask tokens 117std:: copy ( input_tokens , input_tokens + n_input , output_tokens ); 118std:: fill ( output_tokens + n_input , output_tokens + params . max_length , params . mask_token_id ); 119 120std::mt19937 rng ( params . seed ); 121 122llama_set_causal_attn ( ctx , false); 123 124int32_t n_vocab = llama_vocab_n_tokens ( llama_model_get_vocab ( model )); 125 126std::vector < llama_token_data > candidates (n_vocab); 127std::vector < llama_token_data > conf_candidates ; 128conf_candidates . reserve ( params . max_length ); 129std::vector < int32_t > mask_positions ; 130mask_positions . reserve ( params . max_length ); 131 132// Setup sampler chain 133struct llama_sampler * sampler = llama_sampler_chain_init ( llama_sampler_chain_default_params ()); 134if ( params . top_k > 0 ) { 135llama_sampler_chain_add ( sampler , llama_sampler_init_top_k ( params . top_k )); 136} 137if ( params . top_p < 1.0f ) { 138llama_sampler_chain_add ( sampler , llama_sampler_init_top_p ( params . top_p , 1 )); 139} 140if ( params . temperature > 0.0f ) { 141llama_sampler_chain_add ( sampler , llama_sampler_init_temp ( params . temperature )); 142} 143llama_sampler_chain_add ( sampler , llama_sampler_init_dist ( params . seed )); 144 145struct llama_sampler * dist_sampler = llama_sampler_init_dist ( params . seed ); 146 147llama_batch batch = llama_batch_init ( params . max_length , 0 , 1 ); 148batch . n_tokens = params . max_length ; 149 150// Pre-allocate buffers for CFG if needed 151int32_t logits_size = n_vocab * params . max_length ; 152std::vector < float > cond_logits_buffer ; 153std::vector < llama_token > un_x_buffer ; 154if ( params . cfg_scale > 0.0f ) { 155cond_logits_buffer . resize ( logits_size ); 156un_x_buffer . resize ( params . max_length ); 157} 158 159// For block-based processing 160std::vector < int32_t > num_transfer_tokens ; 161int32_t num_blocks = 1 ; 162int32_t steps_per_block = params . steps ; 163 164if ( params . schedule == DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED ) { 165GGML_ASSERT ( params . max_length % params . block_length == 0 ); 166num_blocks = params . max_length / params . block_length ; 167GGML_ASSERT ( params . steps % num_blocks == 0 ); 168steps_per_block = params . steps / num_blocks ; 169} 170 171std::vector < float > confidence ( params . max_length ); 172 173int64_t total_sampling_time = 0 ; 174int64_t total_time = 0 ; 175int64_t time_start = ggml_time_us (); 176 177for (int block_num = 0 ; block_num < num_blocks ; block_num ++ ) { 178int32_t block_start = ( params . schedule == DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED ) ? n_input + block_num * params . block_length : 0 ; 179int32_t block_end = ( params . schedule == DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED ) ? 180std:: min ( n_input + ( block_num + 1 ) * params . block_length , params . max_length ) : 181params . max_length ; 182 183// Count masked tokens in current block for block-based processing 184if ( params . schedule == DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED ) { 185int32_t block_mask_count = 0 ; 186for (int i = block_start ; i < block_end ; i ++ ) { 187if ( output_tokens [ i ] == params . mask_token_id ) { 188block_mask_count ++ ; 189} 190} 191num_transfer_tokens = get_num_transfer_tokens ( block_mask_count , steps_per_block ); 192} 193 194for (int32_t step = 0 ; step < steps_per_block ; step ++ ) { 195int32_t global_step = block_num * steps_per_block + step ; 196 197if ( params . step_callback ) { 198if (! params . step_callback ( 199global_step , params . steps , output_tokens , params . max_length , params . step_callback_user_data )) { 200break ; 201} 202} 203 204// Setup batch 205for (int32_t i = 0 ; i < params . max_length ; i ++ ) { 206batch . token [ i ] = output_tokens [ i ]; 207batch . pos [ i ] = i ; 208batch . n_seq_id [ i ] = 1 ; 209batch . seq_id [ i ][ 0 ] = 0 ; 210batch . logits [ i ] = 1 ; 211} 212 213float * logits = nullptr ; 214 215if ( params . cfg_scale > 0.0f ) { 216int ret = llama_decode ( ctx , batch ); 217if ( ret != 0 ) { 218LOG_ERR ( "Failed to generate conditional" ); 219break ; 220} 221float * cond_logits_ptr = llama_get_logits ( ctx ); 222std:: memcpy ( cond_logits_buffer . data (), cond_logits_ptr , logits_size * sizeof (float)); 223 224// Unconditional generation (mask input) 225std:: copy ( output_tokens , output_tokens + params . max_length , un_x_buffer . begin ()); 226for (int32_t i = 0 ; i < n_input ; i ++ ) { 227un_x_buffer [ i ] = params . mask_token_id ; 228} 229 230for (int32_t i = 0 ; i < params . max_length ; i ++ ) { 231batch . token [ i ] = un_x_buffer [ i ]; 232} 233ret = llama_decode ( ctx , batch ); 234if ( ret != 0 ) { 235LOG_ERR ( "Failed to generate unconditional" ); 236break ; 237} 238float * uncond_logits = llama_get_logits ( ctx ); 239 240// Apply CFG 241for (int32_t i = 0 ; i < logits_size ; i ++ ) { 242cond_logits_buffer [ i ] = 243uncond_logits [ i ] + ( params . cfg_scale + 1.0f ) * ( cond_logits_buffer [ i ] - uncond_logits [ i ]); 244} 245logits = cond_logits_buffer . data (); 246} else { 247int ret = llama_decode ( ctx , batch ); 248if ( ret != 0 ) { 249LOG_ERR ( "%s: failed to decode at step %d, ret = %d\n" , __func__ , global_step , ret ); 250break ; 251} 252logits = llama_get_logits ( ctx ); 253} 254 255if (! logits ) { 256LOG_ERR ( "%s: failed to get logits at step %d\n" , __func__ , global_step ); 257break ; 258} 259 260auto get_logits_for_pos = [ & ](int32_t pos ) -> const float * { 261if ( params . shift_logits ) { 262return pos == 0 ? logits : logits + ( pos - 1 ) * n_vocab ; 263} 264return logits + pos * n_vocab ; 265}; 266 267int64_t time_start_sampling = ggml_time_us (); 268 269mask_positions . clear (); 270for (int32_t i = 0 ; i < params . max_length ; i ++ ) { 271if ( output_tokens [ i ] == params . mask_token_id ) { 272// For block-based, only consider current block 273if ( params . schedule != DIFFUSION_TRANSFER_SCHEDULE_BLOCK_BASED || ( i >= block_start && i < block_end )) { 274mask_positions . push_back ( i ); 275} 276} 277} 278 279if ( mask_positions . empty ()) { 280break ; 281} 282 283if ( params . add_gumbel_noise && params . temperature > 0.0f ) { 284add_gumbel_noise ( logits , n_vocab , params . temperature , rng ); 285} 286 287if ( params . algorithm == DIFFUSION_ALGORITHM_ORIGIN ) { 288int32_t transfer_count = calculate_transfer_count ( 289step , steps_per_block , mask_positions . size (), params . schedule , params . eps , num_transfer_tokens ); 290float p_transfer = (float) transfer_count / mask_positions . size (); 291 292for (int32_t pos : mask_positions ) { 293if (std:: uniform_real_distribution < float > ( 0.0f , 1.0f )( rng ) < p_transfer ) { 294const float * pos_logits = get_logits_for_pos ( pos ); 295for (int32_t token_id = 0 ; token_id < n_vocab ; token_id ++ ) { 296candidates [ token_id ]. id = token_id ; 297candidates [ token_id ]. logit = pos_logits [ token_id ]; 298candidates [ token_id ]. p = 0.0f ; 299} 300 301llama_token_data_array cur_p = { 302candidates . data (), 303(size_t) n_vocab , 304-1 , 305false, 306}; 307 308llama_sampler_apply ( sampler , & cur_p ); 309output_tokens [ pos ] = cur_p . data [ cur_p . selected ]. id ; 310} 311} 312} else { 313std::vector < std::pair < float, int32_t >> confidences ; 314std::vector < llama_token > sampled_tokens ( mask_positions . size ()); 315 316for (size_t i = 0 ; i < mask_positions . size (); i ++ ) { 317int32_t pos = mask_positions [ i ]; 318const float * pos_logits = get_logits_for_pos ( pos ); 319 320for (int32_t token_id = 0 ; token_id < n_vocab ; token_id ++ ) { 321candidates [ token_id ]. logit = pos_logits [ token_id ]; 322candidates [ token_id ]. p = 0.0f ; 323candidates [ token_id ]. id = token_id ; 324} 325 326llama_token_data_array cur_p = { 327candidates . data (), 328candidates . size (), 329-1 , 330false, 331}; 332 333llama_sampler_apply ( sampler , & cur_p ); 334llama_token sampled_token = cur_p . data [ cur_p . selected ]. id ; 335 336float conf = calculate_confidence ( cur_p , params . algorithm , rng ); 337 338sampled_tokens [ i ] = sampled_token ; 339confidences . emplace_back ( conf , i ); 340} 341 342int32_t transfer_count = calculate_transfer_count ( 343step , steps_per_block , mask_positions . size (), params . schedule , params . eps , num_transfer_tokens ); 344 345if ( transfer_count > 0 ) { 346if ( params . alg_temp == 0.0f ) { 347std:: partial_sort ( confidences . begin (), 348confidences . begin () + std:: min ( transfer_count , (int32_t) confidences . size ()), 349confidences . end (), 350[]( const std::pair < float, int32_t > & a , const std::pair < float, int32_t > & b ) { 351if ( a . first != b . first ) { 352return a . first > b . first ; 353} 354return a . second < b . second ; 355}); 356 357for (int32_t i = 0 ; i < std:: min ( transfer_count , (int32_t) confidences . size ()); i ++ ) { 358int32_t mask_idx = confidences [ i ]. second ; 359int32_t pos = mask_positions [ mask_idx ]; 360output_tokens [ pos ] = sampled_tokens [ mask_idx ]; 361} 362} else { 363conf_candidates . clear (); 364for (size_t i = 0 ; i < confidences . size (); i ++ ) { 365float conf_logit = confidences [ i ]. first / params . alg_temp ; 366conf_candidates . emplace_back (llama_token_data{ (int32_t) i , conf_logit , 0.0f }); 367} 368 369llama_token_data_array conf_array = { 370conf_candidates . data (), 371conf_candidates . size (), 372-1 , 373false, 374}; 375 376for (int32_t i = 0 ; i < std:: min ( transfer_count , (int32_t) confidences . size ()); i ++ ) { 377llama_sampler_apply ( dist_sampler , & conf_array ); 378int32_t selected_idx = conf_array . selected ; 379int32_t mask_idx = selected_idx ; 380int32_t pos = mask_positions [ mask_idx ]; 381output_tokens [ pos ] = sampled_tokens [ mask_idx ]; 382 383conf_candidates [ selected_idx ]. p = 0.0f ; 384conf_array . selected = -1 ; 385} 386} 387} 388} 389 390int64_t time_end_sampling = ggml_time_us (); 391total_sampling_time += time_end_sampling - time_start_sampling ; 392} 393} 394 395int64_t time_end = ggml_time_us (); 396total_time += time_end - time_start ; 397 398LOG_INF ( "\ntotal time: %0.2fms, time per step: %0.2fms, sampling time per step: %0.2fms\n" , 399total_time / 1000.0 , 400total_time / 1000.0 / params . steps , 401total_sampling_time / 1000.0 / params . steps ); 402 403llama_batch_free ( batch ); 404llama_sampler_free ( sampler ); 405llama_sampler_free ( dist_sampler ); 406 407n_generated = params . max_length ; 408}