char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
2bb9bddaf
char/aliceai-t5-moe
1#include "arg.h" 2#include "common.h" 3#include "download.h" 4#include "llama.h" 5#include "speculative.h" 6 7#include <cmath> 8#include <limits> 9#include <string> 10#include <vector> 11#include <sstream> 12#include <unordered_set> 13 14#undef NDEBUG 15#include <cassert> 16 17static void test (void ) { 18common_params params ; 19 20auto assert_output_limits = [](int32_t n_batch ,int32_t n_parallel ,int32_t n_draft , 21int32_t total ,int32_t per_seq ) { 22const auto limits = common_speculative_get_output_limits (n_batch ,n_parallel ,n_draft ); 23assert (limits .total == total ); 24assert (limits .per_seq == per_seq ); 25 }; 26 27assert_output_limits (16 ,2 ,3 ,8 ,4 ); 28assert_output_limits (16 ,2 ,-1 ,2 ,1 ); 29assert_output_limits (6 ,2 ,3 ,6 ,4 ); 30assert_output_limits (2 ,1 ,3 ,2 ,2 ); 31assert_output_limits ( 32 std::numeric_limits < int32_t > ::max (), 33 std::numeric_limits < int32_t > ::max (), 34 std::numeric_limits < int32_t > ::max (), 35 std::numeric_limits < int32_t > ::max (), 36 std::numeric_limits < int32_t > ::max ()); 37 38 { 39common_params_speculative spec ; 40spec .synth_len = 3.4 ; 41 42auto assert_invalid = [](const common_params_speculative & value ,int32_t n_max ) { 43try { 44common_speculative_synth_rates_resolve (& value ,n_max ); 45assert (false); 46 }catch (const std::invalid_argument & ) { 47 } 48 }; 49 50const auto rates = common_speculative_synth_rates_resolve (& spec ,4 ); 51assert (rates .size ()== 4 ); 52assert (std::abs (rates [0 ]- 0.80581 )< 1e-5 ); 53assert (std::abs (rates [1 ]- 0.64933 )< 1e-5 ); 54assert (std::abs (rates [2 ]- 0.52323 )< 1e-5 ); 55assert (std::abs (rates [3 ]- 0.42163 )< 1e-5 ); 56assert (std::abs (1.0 + rates [0 ]+ rates [1 ]+ rates [2 ]+ rates [3 ]- 3.4 )< 1e-8 ); 57 58spec .synth_len = 1.0 ; 59assert (common_speculative_synth_rates_resolve (& spec ,4 )== std::vector < double > ({0.0 ,0.0 ,0.0 ,0.0 })); 60 61spec .synth_len = 5.0 ; 62assert (common_speculative_synth_rates_resolve (& spec ,4 )== std::vector < double > ({1.0 ,1.0 ,1.0 ,1.0 })); 63 64spec .synth_len = 5.1 ; 65assert_invalid (spec ,4 ); 66 67spec .synth_len = std::numeric_limits < double > ::quiet_NaN (); 68assert_invalid (spec ,4 ); 69 70spec .synth_len = 0.0 ; 71assert_invalid (spec ,4 ); 72 73spec .synth_len = -1.0 ; 74spec .synth_rates = {0.8 ,0.6 ,0.4 }; 75assert_invalid (spec ,4 ); 76 77spec .synth_rates = {0.8 ,0.6 ,0.4 ,0.2 }; 78assert (common_speculative_synth_rates_resolve (& spec ,4 )== spec .synth_rates ); 79 80spec .synth_rates = {0.8 ,0.9 ,0.4 ,0.2 }; 81assert_invalid (spec ,4 ); 82 83spec .synth_rates = {0.8 , std::numeric_limits < double > ::quiet_NaN (),0.4 ,0.2 }; 84assert_invalid (spec ,4 ); 85 86spec .synth_rates = {0.8 ,0.6 ,0.4 ,-0.2 }; 87assert_invalid (spec ,4 ); 88 89spec .synth_rates = {0.8 ,0.6 ,0.4 ,0.2 }; 90spec .synth_len = 3.0 ; 91assert_invalid (spec ,4 ); 92 } 93 94 { 95common_params base ; 96base .n_parallel = 4 ; 97base .n_outputs_max_per_seq = 8 ; 98 99const auto draft = common_base_params_to_speculative (base ); 100assert (draft .n_outputs_max == 4 ); 101assert (draft .n_outputs_max_per_seq == 1 ); 102 } 103 104printf ("test-arg-parser: make sure there is no duplicated arguments in any examples\n\n" ); 105for (int ex = 0 ;ex < LLAMA_EXAMPLE_COUNT ;ex ++ ) { 106try { 107auto ctx_arg = common_params_parser_init (params , (enum llama_example )ex ); 108common_params_add_preset_options (ctx_arg .options ); 109 std::unordered_set < std::string > seen_args ; 110 std::unordered_set < std::string > seen_env_vars ; 111for (const auto & opt :ctx_arg .options ) { 112// check for args duplications 113for (const auto & arg :opt .get_args ()) { 114if (seen_args .find (arg )== seen_args .end ()) { 115seen_args .insert (arg ); 116 }else { 117fprintf (stderr ,"test-arg-parser: found different handlers for the same argument: %s" ,arg .c_str ()); 118exit (1 ); 119 } 120 } 121// check for env var duplications 122for (const auto & env :opt .get_env ()) { 123if (seen_env_vars .find (env )== seen_env_vars .end ()) { 124seen_env_vars .insert (env ); 125 }else { 126fprintf (stderr ,"test-arg-parser: found different handlers for the same env var: %s" ,env .c_str ()); 127exit (1 ); 128 } 129 } 130 131// exclude spec args from this check 132// ref: https://github.com/ggml-org/llama.cpp/pull/22397 133const bool skip = opt .is_spec ; 134 135// ensure shorter argument precedes longer argument 136if (!skip && opt .args .size ()> 1 ) { 137const std::string first (opt .args .front ()); 138const std::string last (opt .args .back ()); 139 140if (first .length ()> last .length ()) { 141fprintf (stderr ,"test-arg-parser: shorter argument should come before longer one: %s, %s\n" , 142first .c_str (),last .c_str ()); 143assert (false); 144 } 145 } 146 147// same check for negated arguments 148if (opt .args_neg .size ()> 1 ) { 149const std::string first (opt .args_neg .front ()); 150const std::string last (opt .args_neg .back ()); 151 152if (first .length ()> last .length ()) { 153fprintf (stderr ,"test-arg-parser: shorter negated argument should come before longer one: %s, %s\n" , 154first .c_str (),last .c_str ()); 155assert (false); 156 } 157 } 158 } 159 }catch (std::exception & e ) { 160printf ("%s\n" ,e .what ()); 161assert (false); 162 } 163 } 164 165auto list_str_to_char = [](std::vector < std::string > & argv )-> std::vector < char *> { 166 std::vector < char *> res ; 167for (auto & arg :argv ) { 168res .push_back (const_cast < char *> (arg .data ())); 169 } 170return res ; 171 }; 172 173 std::vector < std::string > argv ; 174 175printf ("test-arg-parser: test invalid usage\n\n" ); 176 177// missing value 178argv = {"binary_name" ,"-m" }; 179assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 180 181// wrong value (int) 182argv = {"binary_name" ,"-ngl" ,"hello" }; 183assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 184 185// wrong value (enum) 186argv = {"binary_name" ,"-sm" ,"hello" }; 187assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 188 189 { 190common_params penalty_params ; 191assert (penalty_params .sampling .penalty_last_n == 64 ); 192assert (penalty_params .sampling .dry_penalty_last_n == 64 ); 193 194argv = {"binary_name" ,"--repeat-last-n" ,"-1" }; 195assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 196 197argv = {"binary_name" ,"--dry-penalty-last-n" ,"-1" }; 198assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 199 200argv = {"binary_name" ,"--repeat-penalty" ,"0" }; 201assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 202 203argv = {"binary_name" ,"--repeat-penalty" ,"-1" }; 204assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 205 206argv = {"binary_name" ,"--repeat-penalty" ,"nan" }; 207assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 208 209argv = {"binary_name" ,"--repeat-penalty" ,"inf" }; 210assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 211 212argv = {"binary_name" ,"--repeat-penalty" ,"-inf" }; 213assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 214 215const char * penalty_options []= {"--frequency-penalty" ,"--presence-penalty" }; 216const char * nonfinite_values []= {"nan" ,"inf" ,"-inf" }; 217for (const char * option :penalty_options ) { 218for (const char * value :nonfinite_values ) { 219argv = {"binary_name" ,option ,value }; 220assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),penalty_params ,LLAMA_EXAMPLE_COMMON )); 221 } 222 } 223 } 224 225// non-existence arg in specific example (--draft cannot be used outside llama-speculative) 226argv = {"binary_name" ,"--draft" ,"123" }; 227assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_EMBEDDING )); 228 229argv = {"binary_name" ,"-lm" ,"hello" }; 230assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 231 232printf ("test-arg-parser: test valid usage\n\n" ); 233 234argv = {"binary_name" ,"-m" ,"model_file.gguf" }; 235assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 236assert (params .model .path == "model_file.gguf" ); 237 238argv = {"binary_name" ,"-t" ,"1234" }; 239assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 240assert (params .cpuparams .n_threads == 1234 ); 241 242argv = {"binary_name" ,"--verbose" }; 243assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 244assert (params .verbosity > 1 ); 245 246argv = {"binary_name" ,"-m" ,"abc.gguf" ,"--predict" ,"6789" ,"--batch-size" ,"9090" }; 247assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 248assert (params .model .path == "abc.gguf" ); 249assert (params .n_predict == 6789 ); 250assert (params .n_batch == 9090 ); 251 252// --draft cannot be used outside llama-speculative 253argv = {"binary_name" ,"--spec-draft-n-max" ,"123" }; 254assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_SPECULATIVE )); 255assert (params .speculative .draft .n_max == 123 ); 256 257 { 258common_params synth_params ; 259argv = {"binary_name" ,"--spec-synth-len" ,"3.4" }; 260assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),synth_params ,LLAMA_EXAMPLE_SERVER )); 261assert (synth_params .speculative .synth_len == 3.4 ); 262 } 263 264 { 265common_params synth_params ; 266argv = {"binary_name" ,"--spec-synth-rates" ,"0.8,0.6,0.2" }; 267assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),synth_params ,LLAMA_EXAMPLE_SERVER )); 268assert (synth_params .speculative .synth_rates == std::vector < double > ({0.8 ,0.6 ,0.2 })); 269 } 270 271 { 272common_params synth_params ; 273argv = {"binary_name" ,"--spec-synth-len" ,"3.4x" }; 274assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),synth_params ,LLAMA_EXAMPLE_SERVER )); 275 } 276 277argv = {"binary_name" ,"-lm" ,"none" }; 278assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 279assert (params .load_mode == LLAMA_LOAD_MODE_NONE ); 280 281argv = {"binary_name" ,"-lm" ,"mmap" }; 282assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 283assert (params .load_mode == LLAMA_LOAD_MODE_MMAP ); 284 285argv = {"binary_name" ,"-lm" ,"mlock" }; 286assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 287assert (params .load_mode == LLAMA_LOAD_MODE_MLOCK ); 288 289argv = {"binary_name" ,"-lm" ,"mmap+mlock" }; 290assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 291assert (params .load_mode == LLAMA_LOAD_MODE_MMAP_MLOCK ); 292 293argv = {"binary_name" ,"-lm" ,"dio" }; 294assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 295assert (params .load_mode == LLAMA_LOAD_MODE_DIRECT_IO ); 296 297// multi-value args (CSV) 298argv = {"binary_name" ,"--lora" ,"file1.gguf,\"file2,2.gguf\",\"file3\"\"3\"\".gguf\",file4\".gguf" }; 299assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 300assert (params .lora_adapters .size ()== 4 ); 301assert (params .lora_adapters [0 ].path == "file1.gguf" ); 302assert (params .lora_adapters [1 ].path == "file2,2.gguf" ); 303assert (params .lora_adapters [2 ].path == "file3\"3\".gguf" ); 304assert (params .lora_adapters [3 ].path == "file4\".gguf" ); 305 306// skip this part on windows, because setenv is not supported 307#ifdef _WIN32 308printf ("test-arg-parser: skip on windows build\n" ); 309#else 310printf ("test-arg-parser: test environment variables (valid + invalid usages)\n\n" ); 311 312setenv ("LLAMA_ARG_THREADS" ,"blah" , true); 313argv = {"binary_name" }; 314assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 315 316setenv ("LLAMA_ARG_MODEL" ,"blah.gguf" , true); 317setenv ("LLAMA_ARG_THREADS" ,"1010" , true); 318argv = {"binary_name" }; 319assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 320assert (params .model .path == "blah.gguf" ); 321assert (params .cpuparams .n_threads == 1010 ); 322 323setenv ("LLAMA_ARG_LOAD_MODE" ,"blah" , true); 324argv = {"binary_name" }; 325assert (false== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 326 327setenv ("LLAMA_ARG_LOAD_MODE" ,"mmap" , true); 328argv = {"binary_name" }; 329assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 330assert (params .load_mode == LLAMA_LOAD_MODE_MMAP ); 331 332setenv ("LLAMA_ARG_LOAD_MODE" ,"mlock" , true); 333argv = {"binary_name" }; 334assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 335assert (params .load_mode == LLAMA_LOAD_MODE_MLOCK ); 336 337setenv ("LLAMA_ARG_LOAD_MODE" ,"mmap+mlock" , true); 338argv = {"binary_name" }; 339assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 340assert (params .load_mode == LLAMA_LOAD_MODE_MMAP_MLOCK ); 341 342setenv ("LLAMA_ARG_LOAD_MODE" ,"dio" , true); 343argv = {"binary_name" }; 344assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 345assert (params .load_mode == LLAMA_LOAD_MODE_DIRECT_IO ); 346 347printf ("test-arg-parser: test negated environment variables\n\n" ); 348 349setenv ("LLAMA_ARG_LOAD_MODE" ,"none" , true); 350setenv ("LLAMA_ARG_NO_PERF" ,"1" , true);// legacy format 351argv = {"binary_name" }; 352assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 353assert (params .load_mode == LLAMA_LOAD_MODE_NONE ); 354assert (params .no_perf == true); 355 356printf ("test-arg-parser: test environment variables being overwritten\n\n" ); 357 358setenv ("LLAMA_ARG_MODEL" ,"blah.gguf" , true); 359setenv ("LLAMA_ARG_THREADS" ,"1010" , true); 360argv = {"binary_name" ,"-m" ,"overwritten.gguf" }; 361assert (true== common_params_parse (argv .size (),list_str_to_char (argv ).data (),params ,LLAMA_EXAMPLE_COMMON )); 362assert (params .model .path == "overwritten.gguf" ); 363assert (params .cpuparams .n_threads == 1010 ); 364#endif // _WIN32 365 366printf ("test-arg-parser: test download functions\n\n" ); 367const char * GOOD_URL = "http://ggml.ai/" ; 368const char * BAD_URL = "http://ggml.ai/404" ; 369 370 { 371printf ("test-arg-parser: test good URL\n\n" ); 372auto res = common_remote_get_content (GOOD_URL , {}); 373assert (res .first == 200 ); 374assert (res .second .size ()> 0 ); 375 std::string str (res .second .data (),res .second .size ()); 376assert (str .find ("llama.cpp" )!= std::string::npos ); 377 } 378 379 { 380printf ("test-arg-parser: test bad URL\n\n" ); 381auto res = common_remote_get_content (BAD_URL , {}); 382assert (res .first == 404 ); 383 } 384 385 { 386printf ("test-arg-parser: test max size error\n" ); 387common_remote_params params ; 388params .max_size = 1 ; 389try { 390common_remote_get_content (GOOD_URL ,params ); 391assert (false&& "it should throw an error" ); 392 }catch (std::exception & e ) { 393printf (" expected error: %s\n\n" ,e .what ()); 394 } 395 } 396 397printf ("test-arg-parser: all tests OK\n\n" ); 398} 399 400int main (void ) { 401try { 402test (); 403 }catch (std::exception & e ) { 404fprintf (stderr ,"test-arg-parser: exception: %s\n" ,e .what ()); 405return 1 ; 406 } 407return 0 ; 408}