| 442 | } |
| 443 | |
| 444 | static results_perplexity perplexity(llama_context * ctx, const common_params & params, const int32_t n_ctx) { |
| 445 | if (params.ppl_stride > 0) { |
| 446 | return perplexity_v2(ctx, params); |
| 447 | } |
| 448 | |
| 449 | // Download: https://huggingface.co/datasets/ggml-org/ci/resolve/main/wikitext-2-raw-v1.zip |
| 450 | // Run `./llama-perplexity -m models/7B/ggml-model-q4_0.bin -f wiki.test.raw` |
| 451 | // Output: `perplexity: 13.5106 [114/114]` |
| 452 | // BOS tokens will be added for each chunk before eval |
| 453 | |
| 454 | const llama_model * model = llama_get_model(ctx); |
| 455 | const llama_vocab * vocab = llama_model_get_vocab(model); |
| 456 | |
| 457 | const bool add_bos = llama_vocab_get_add_bos(vocab); |
| 458 | GGML_ASSERT(!llama_vocab_get_add_eos(vocab)); |
| 459 | |
| 460 | std::ofstream logits_stream; |
| 461 | if (!params.logits_file.empty()) { |
| 462 | logits_stream.open(params.logits_file.c_str(), std::ios::binary); |
| 463 | if (!logits_stream.is_open()) { |
| 464 | LOG_ERR("%s: failed to open %s for writing\n", __func__, params.logits_file.c_str()); |
| 465 | return {}; |
| 466 | } |
| 467 | LOG_INF("%s: saving all logits to %s\n", __func__, params.logits_file.c_str()); |
| 468 | logits_stream.write("_logits_", 8); |
| 469 | logits_stream.write(reinterpret_cast<const char *>(&n_ctx), sizeof(n_ctx)); |
| 470 | } |
| 471 | |
| 472 | auto tim1 = std::chrono::high_resolution_clock::now(); |
| 473 | LOG_INF("%s: tokenizing the input ..\n", __func__); |
| 474 | |
| 475 | std::vector<llama_token> tokens = common_tokenize(ctx, params.prompt, true); |
| 476 | |
| 477 | auto tim2 = std::chrono::high_resolution_clock::now(); |
| 478 | LOG_INF("%s: tokenization took %g ms\n",__func__,1e-3*std::chrono::duration_cast<std::chrono::microseconds>(tim2-tim1).count()); |
| 479 | |
| 480 | if (int(tokens.size()) < 2*n_ctx) { |
| 481 | LOG_ERR("%s: you need at least %d tokens to evaluate perplexity with a context of %d\n",__func__,2*n_ctx, |
| 482 | n_ctx); |
| 483 | LOG_ERR("%s: the data file you provided tokenizes to only %zu tokens\n",__func__,tokens.size()); |
| 484 | return {std::move(tokens), 0., {}, {}}; |
| 485 | } |
| 486 | |
| 487 | std::vector<float> logit_history; |
| 488 | logit_history.resize(tokens.size()); |
| 489 | |
| 490 | std::vector<float> prob_history; |
| 491 | prob_history.resize(tokens.size()); |
| 492 | |
| 493 | const int n_chunk_max = tokens.size() / n_ctx; |
| 494 | |
| 495 | const int n_chunk = params.n_chunks < 0 ? n_chunk_max : std::min(params.n_chunks, n_chunk_max); |
| 496 | const int n_batch = params.n_batch; |
| 497 | |
| 498 | const int n_vocab = llama_vocab_n_tokens(vocab); |
| 499 | |
| 500 | int count = 0; |
| 501 | double nll = 0.0; |
no test coverage detected