CoolFace
Modelpublic

Felipe97/llama-cpp-compiled

sourceHugging Faceupdated 2d agoView on Hugging Face
0likes1.1kdownloads
test-backend-sampler.cpp2168 linesDownload Raw Back to tests
1#include "ggml.h"2#include "llama.h"3#include "llama-cpp.h"4#include "common.h"5 6#ifdef NDEBUG7#undef NDEBUG8#endif9 10#include <algorithm>11#include <cmath>12#include <cstdlib>13#include <cstring>14#include <fstream>15#include <functional>16#include <map>17#include <random>18#include <string>19#include <unordered_map>20#include <unordered_set>21#include <vector>22 23struct test_args {24    std::string model;25    std::string test;26    std::string device = "auto";27};28 29struct test_params {30    llama_model_ptr model;31};32 33static llama_model_ptr load_model(const test_args & args) {34    auto mparams = llama_model_default_params();35 36    ggml_backend_dev_t devs[2] = { nullptr, nullptr };37 38    if (args.device != "auto") {39        if (args.device == "gpu") {40            devs[0] = ggml_backend_dev_by_type(GGML_BACKEND_DEVICE_TYPE_GPU);41 42            if (devs[0] == nullptr) {43                fprintf(stderr, "Error: GPU requested but not available\n");44                return nullptr;45            }46 47            mparams.n_gpu_layers = 999;48        } else if (args.device == "cpu") {49            devs[0] = ggml_backend_dev_by_type(GGML_BACKEND_DEVICE_TYPE_CPU);50 51            mparams.n_gpu_layers = 0;52        } else {53            fprintf(stderr, "Error: invalid device '%s'\n", args.device.c_str());54            return nullptr;55        }56 57        mparams.devices = devs;58 59        fprintf(stderr, "Using device: %s\n", ggml_backend_dev_name(devs[0]));60    }61 62    llama_model_ptr res;63 64    res.reset(llama_model_load_from_file(args.model.c_str(), mparams));65 66    if (!res) {67        fprintf(stderr, "Warning: failed to load model '%s', skipping test\n", args.model.c_str());68        return nullptr;69    }70 71    return res;72}73 74struct test_context {75    llama_context_ptr ctx;76 77    int n_vocab = 0;78 79    const llama_vocab * vocab = nullptr;80 81    std::unordered_map<llama_seq_id, int32_t> seq_positions;82    std::unordered_map<llama_seq_id, int32_t> last_batch_info;83 84    test_context(85            const test_params & params,86            std::vector<llama_sampler_seq_config> & configs,87            int32_t n_seq_max = -1,88            uint32_t n_outputs_max = 0,89            uint32_t n_ubatch = 0,90            uint32_t n_outputs_max_per_seq = 1) {91        auto * model = params.model.get();92 93        GGML_ASSERT(model);94        GGML_ASSERT(!ctx);95 96        llama_context_params cparams = llama_context_default_params();97        cparams.n_ctx = 512;98        cparams.n_batch = 512;99        if (n_ubatch > 0) {100            cparams.n_ubatch = n_ubatch;101        }102        cparams.n_outputs_max = n_outputs_max;103        cparams.n_outputs_max_per_seq = n_outputs_max_per_seq;104        cparams.samplers = configs.data();105        cparams.n_samplers = configs.size();106        cparams.kv_unified = true;107 108        // If n_seq_max is not specified, calculate it from configs109        if (n_seq_max < 0) {110            int32_t max_seq_id = 0;111            for (const auto & config : configs) {112                max_seq_id = std::max(config.seq_id, max_seq_id);113            }114            cparams.n_seq_max = max_seq_id + 1;115        } else {116            cparams.n_seq_max = n_seq_max;117        }118 119        ctx.reset(llama_init_from_model(model, cparams));120        if (!ctx) {121            throw std::runtime_error("failed to create context");122        }123 124        vocab = llama_model_get_vocab(model);125        n_vocab = llama_vocab_n_tokens(vocab);126    }127 128    bool decode(const std::map<llama_seq_id, std::string> & prompts) {129        GGML_ASSERT(ctx);130 131        last_batch_info.clear();132        llama_batch batch = llama_batch_init(512, 0, prompts.size());133 134        for (const auto & [seq_id, prompt] : prompts) {135            std::vector<llama_token> tokens;136            tokens.push_back(llama_vocab_bos(vocab));137 138            std::vector<llama_token> prompt_tokens(32);139            int n_tokens = llama_tokenize(vocab, prompt.c_str(), prompt.length(),140                                           prompt_tokens.data(), prompt_tokens.size(),141                                           false, false);142            if (n_tokens < 0) {143                fprintf(stderr, "Warning: tokenization failed for seq_id %d\n", seq_id);144                llama_batch_free(batch);145                return false;146            }147 148            for (int i = 0; i < n_tokens; i++) {149                tokens.push_back(prompt_tokens[i]);150            }151 152            if (seq_positions.find(seq_id) == seq_positions.end()) {153                seq_positions[seq_id] = 0;154            }155 156            int32_t start_pos = seq_positions[seq_id];157            for (size_t i = 0; i < tokens.size(); i++) {158                common_batch_add(batch, tokens[i], start_pos + i, { seq_id }, i == tokens.size() - 1);159            }160 161            seq_positions[seq_id] = start_pos + tokens.size();162        }163 164 165        printf("Batch contents:\n");166        printf("n_tokens: %d\n", batch.n_tokens);167        for (int i = 0; i < batch.n_tokens; i++) {168            printf("token[%d]: tok=%-5d, pos=%d, n_seq_id=%d, seq_ids=[", i, batch.token[i], batch.pos[i], batch.n_seq_id[i]);169 170            for (int j = 0; j < batch.n_seq_id[i]; j++) {171                printf("%d%s", batch.seq_id[i][j], j < batch.n_seq_id[i]-1 ? ", " : "");172            }173            printf("], logits=%d\n", batch.logits[i]);174        }175 176        if (llama_decode(ctx.get(), batch) != 0) {177            fprintf(stderr, "Warning: llama_decode failed\n");178            llama_batch_free(batch);179            return false;180        }181 182        // Build mapping from seq id to batch token idx183        for (int i = 0; i < batch.n_tokens; i++) {184            if (batch.logits[i]) {185                llama_seq_id seq_id = batch.seq_id[i][0];186                last_batch_info[seq_id] = i;187            }188        }189 190        llama_batch_free(batch);191        return true;192    }193 194    int32_t idx_for_seq(llama_seq_id seq_id) {195        auto it = last_batch_info.find(seq_id);196        if (it == last_batch_info.end()) {197            fprintf(stderr, "Error: no batch index found for seq_id %d\n", seq_id);198            return -1;199        }200        return it->second;201    }202 203    void update_batch_info(const llama_batch & batch) {204        last_batch_info.clear();205        for (int i = 0; i < batch.n_tokens; i++) {206            if (batch.logits[i]) {207                llama_seq_id cur_seq = batch.seq_id[i][0];208                last_batch_info[cur_seq] = i;209            }210        }211    }212 213    bool decode_token(llama_token token, llama_seq_id seq_id = 0) {214        GGML_ASSERT(ctx);215 216        llama_batch batch = llama_batch_init(1, 0, 1);217        int32_t pos = seq_positions[seq_id];218        common_batch_add(batch, token, pos, { seq_id }, true);219 220        if (llama_decode(ctx.get(), batch) != 0) {221            fprintf(stderr, "Warning: llama_decode failed for token %d in seq %d\n", token, seq_id);222            llama_batch_free(batch);223            return false;224        }225 226        update_batch_info(batch);227 228        seq_positions[seq_id]++;229        llama_batch_free(batch);230 231        return true;232    }233 234    bool decode_tokens(const std::map<llama_seq_id, llama_token> & seq_tokens) {235        GGML_ASSERT(ctx);236 237        llama_batch batch = llama_batch_init(seq_tokens.size(), 0, seq_tokens.size());238 239        for (const auto & [seq_id, token] : seq_tokens) {240            int32_t pos = seq_positions[seq_id];241            common_batch_add(batch, token, pos, { seq_id }, true);242        }243 244        if (llama_decode(ctx.get(), batch) != 0) {245            fprintf(stderr, "Warning: llama_decode failed for batch tokens\n");246            llama_batch_free(batch);247            return false;248        }249 250        for (const auto & [seq_id, _] : seq_tokens) {251            seq_positions[seq_id]++;252        }253 254        update_batch_info(batch);255 256        llama_batch_free(batch);257 258        return true;259    }260 261    std::string token_to_piece(llama_token token, bool special) const {262        std::string piece;263        piece.resize(piece.capacity());  // using string internal cache, 15 bytes + '\n'264        const int n_chars = llama_token_to_piece(vocab, token, &piece[0], piece.size(), 0, special);265        if (n_chars < 0) {266            piece.resize(-n_chars);267            int check = llama_token_to_piece(vocab, token, &piece[0], piece.size(), 0, special);268            GGML_ASSERT(check == -n_chars);269        } else {270            piece.resize(n_chars);271        }272 273        return piece;274    }275};276 277struct test_single_output_backend_sampler {278    bool backend_initialized = false;279    uint32_t backend_outputs_max_per_seq = 0;280    int backend_apply_count = 0;281    int apply_count = 0;282};283 284static const char * test_single_output_backend_sampler_name(const llama_sampler * /*smpl*/) {285    return "single-output-backend";286}287 288static void test_single_output_backend_sampler_apply(289        llama_sampler * smpl, llama_token_data_array * /*cur_p*/) {290    auto * ctx = (test_single_output_backend_sampler *) smpl->ctx;291    ctx->apply_count++;292}293 294static void test_single_output_backend_sampler_free(llama_sampler * smpl) {295    delete (test_single_output_backend_sampler *) smpl->ctx;296}297 298static bool test_single_output_backend_sampler_backend_init(299        llama_sampler * smpl, ggml_backend_buffer_type_t /*buft*/, uint32_t n_outputs_max_per_seq) {300    auto * ctx = (test_single_output_backend_sampler *) smpl->ctx;301    ctx->backend_outputs_max_per_seq = n_outputs_max_per_seq;302    if (n_outputs_max_per_seq > 1) {303        return false;304    }305    ctx->backend_initialized = true;306    return true;307}308 309static void test_single_output_backend_sampler_backend_apply(310        llama_sampler * smpl, ggml_context * /*ctx*/, ggml_cgraph * /*gf*/, llama_sampler_data * /*data*/) {311    auto * ctx = (test_single_output_backend_sampler *) smpl->ctx;312    ctx->backend_apply_count++;313}314 315static llama_sampler_i test_single_output_backend_sampler_i = {316    /* .name              = */ test_single_output_backend_sampler_name,317    /* .accept            = */ nullptr,318    /* .apply             = */ test_single_output_backend_sampler_apply,319    /* .reset             = */ nullptr,320    /* .clone             = */ nullptr,321    /* .free              = */ test_single_output_backend_sampler_free,322    /* .backend_init      = */ test_single_output_backend_sampler_backend_init,323    /* .backend_accept    = */ nullptr,324    /* .backend_apply     = */ test_single_output_backend_sampler_backend_apply,325    /* .backend_set_input = */ nullptr,326    /* .backend_reset     = */ nullptr,327    /* .copy_state        = */ nullptr,328};329 330static llama_sampler * test_single_output_backend_sampler_init(331        test_single_output_backend_sampler ** sampler_ctx) {332    auto * ctx = new test_single_output_backend_sampler;333    *sampler_ctx = ctx;334    return llama_sampler_init(&test_single_output_backend_sampler_i, ctx);335}336 337static void test_backend_greedy_sampling(const test_params & params) {338    const int seq_id = 0;339 340    struct llama_sampler_chain_params backend_sampler_params = llama_sampler_chain_default_params();341    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_sampler_params));342 343    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_greedy());344    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};345 346    test_context test_ctx(params, backend_sampler_configs);347 348    if (!test_ctx.decode({{seq_id, "Some"}})) {349        GGML_ASSERT(false && "Failed to decode token");350    }351 352    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);353 354    llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), batch_idx);355    printf("greedy sampled id:%d, string:'%s'\n", token, test_ctx.token_to_piece(token, false).c_str());356    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);357 358    token = llama_get_sampled_token_ith(test_ctx.ctx.get(), -1);359    printf("greedy sampled id:%d, string:'%s'\n", token, test_ctx.token_to_piece(token, false).c_str());360    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);361 362    for (int i = 0; i < 10; i++) {363        int32_t loop_idx = test_ctx.idx_for_seq(seq_id);364        llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), loop_idx);365        printf("Generation step %d: token id:%d, string: %s\n", i, token, test_ctx.token_to_piece(token, false).c_str());366        if (!test_ctx.decode_token(token, 0)) {367            GGML_ASSERT(false && "Failed to decode token");368        }369    }370}371 372static void test_backend_top_k_sampling(const test_params & params) {373    const int seq_id = 0;374    const int32_t k = 8;375    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();376    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));377    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_top_k(k));378    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};379 380    test_context test_ctx(params, backend_sampler_configs);381 382    if (!test_ctx.decode({{seq_id, "Hello"}})) {383        GGML_ASSERT(false && "Failed to decode token");384    }385 386    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);387 388    float * logits = llama_get_sampled_logits_ith(test_ctx.ctx.get(), batch_idx);389    uint32_t n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);390    for (size_t i = 0; i < n_logits; ++i) {391        printf("top_k logit[%zu] = %.6f\n", i, logits[i]);392    }393 394    llama_token * candidates = llama_get_sampled_candidates_ith(test_ctx.ctx.get(), batch_idx);395    uint32_t n_candidates = llama_get_sampled_candidates_count_ith(test_ctx.ctx.get(), batch_idx);396    for (size_t i = 0; i < n_candidates; ++i) {397        printf("top_k candidate[%zu] = %d : %s\n", i, candidates[i],398               test_ctx.token_to_piece(candidates[i], false).c_str());399    }400 401    // Sample using CPU sampler for verification that it is possible to do hybrid402    // sampling, first top_k on the backend and then dist on the CPU.403    struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();404    llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));405    GGML_ASSERT(chain->iface->backend_apply != nullptr);406 407    llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(18));408    llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);409    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);410 411    printf("backend top-k hybrid sampling test PASSED\n");412}413 414static void test_backend_temp_sampling(const test_params & params) {415    {416        const float temp_0 = 0.8f;417        struct llama_sampler_chain_params backend_chain_params_0 = llama_sampler_chain_default_params();418        llama_sampler_ptr backend_sampler_chain_0(llama_sampler_chain_init(backend_chain_params_0));419        llama_sampler_chain_add(backend_sampler_chain_0.get(), llama_sampler_init_temp(temp_0));420 421        const float temp_1 = 0.1f;422        struct llama_sampler_chain_params backend_chain_params_1 = llama_sampler_chain_default_params();423        llama_sampler_ptr backend_sampler_chain_1(llama_sampler_chain_init(backend_chain_params_1));424        llama_sampler_chain_add(backend_sampler_chain_1.get(), llama_sampler_init_temp(temp_1));425 426        std::vector<llama_sampler_seq_config> backend_sampler_configs = {427            { 0, backend_sampler_chain_0.get() },428            { 1, backend_sampler_chain_1.get() }429        };430 431        test_context test_ctx(params, backend_sampler_configs);432 433        if (!test_ctx.decode({{0, "Some where over the"}, {1, "Once upon a"}})) {434            GGML_ASSERT(false && "Failed to decode token");435        }436 437        // Verify sequence 0438        {439            int32_t batch_idx = test_ctx.idx_for_seq(0);440            int n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);441            GGML_ASSERT(n_logits == test_ctx.n_vocab);442 443            // Sample from sequence 0 using CPU sampler444            struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();445            llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));446            llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(18));447 448            llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);449            const std::string token_str = test_ctx.token_to_piece(token, false);450            printf("Sequence 0 sampled token id:%d, string: '%s'\n", token, token_str.c_str());451            GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);452        }453 454 455        // Verify sequence 1456        {457            int32_t batch_idx = test_ctx.idx_for_seq(1);458 459            // Sample from sequence 1 using CPU sampler460            struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();461            llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));462            llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(18));463 464            llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);465            const std::string token_str = test_ctx.token_to_piece(token, false);466            printf("Sequence 1 sampled token id:%d, string: '%s'\n", token, token_str.c_str());467            GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);468        }469    }470 471    // lambda for testing non-positive temperature values.472    auto test_argmax_temp = [&](float temp) {473        printf("\nTesting temperature = %.1f\n", temp);474 475        int seq_id = 0;476        struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();477        llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));478        llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_temp(temp));479 480        std::vector<llama_sampler_seq_config> backend_sampler_configs = {481            { seq_id, backend_sampler_chain.get() },482        };483 484        test_context test_ctx(params, backend_sampler_configs);485 486        if (!test_ctx.decode({{seq_id, "Once"}})) {487            GGML_ASSERT(false && "Failed to decode token");488        }489 490        int32_t batch_idx = test_ctx.idx_for_seq(seq_id);491 492        uint32_t n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);493        GGML_ASSERT(n_logits == 1);494    };495 496    test_argmax_temp(0.0f);497    test_argmax_temp(-1.0f);498 499    printf("backend temp sampling test PASSED\n");500}501 502static void test_backend_temp_ext_sampling(const test_params & params) {503    {504        int seq_id = 0;505        const float temp = 0.8f;506        const float delta = 0.5f;507        const float exponent = 1.5f;508        struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();509        llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));510        llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_temp_ext(temp, delta, exponent));511 512        std::vector<llama_sampler_seq_config> backend_sampler_configs = {513            { seq_id, backend_sampler_chain.get() },514        };515 516        test_context test_ctx(params, backend_sampler_configs);517 518        if (!test_ctx.decode({{seq_id, "Once upon a"}})) {519            GGML_ASSERT(false && "Failed to decode token");520        }521 522        // Verify sequence 0523        {524            int32_t batch_idx = test_ctx.idx_for_seq(seq_id);525            int n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);526            GGML_ASSERT(n_logits == test_ctx.n_vocab);527        }528    }529 530    // lambda for testing non-positive temp/delta/exponent values.531    auto test_argmax_temp = [&](float temp, float delta, float exponent) {532        printf("\nTesting temperature = %.1f, delta = %1.f, exponent = %1.f\n", temp, delta, exponent);533 534        int seq_id = 0;535        struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();536        llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));537        llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_temp_ext(temp, delta, exponent));538 539        std::vector<llama_sampler_seq_config> backend_sampler_configs = {540            { seq_id, backend_sampler_chain.get() },541        };542 543        test_context test_ctx(params, backend_sampler_configs);544 545        if (!test_ctx.decode({{seq_id, "Once"}})) {546            GGML_ASSERT(false && "Failed to decode token");547        }548 549        int32_t batch_idx = test_ctx.idx_for_seq(seq_id);550 551        uint32_t n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);552 553        if (temp <= 0.0f && delta >= 0.0f) {554            GGML_ASSERT(n_logits == 1);555        } else {556            GGML_ASSERT(n_logits == (uint32_t) test_ctx.n_vocab);557        }558    };559 560    test_argmax_temp(0.0f,  0.3f, 1.0f); // Greedy (temp=0)561    test_argmax_temp(-1.0f, 0.3f, 2.0f); // Greedy (temp<0)562    test_argmax_temp(0.8f,  0.0f, 2.0f); // Temperature scaling563 564    printf("backend temp_ext sampling test PASSED\n");565}566 567static void test_backend_min_p_sampling(const test_params & params) {568    const int seq_id = 0;569    const float p = 0.1;570    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();571    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));572    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_min_p(p, 0));573    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};574 575    test_context test_ctx(params, backend_sampler_configs);576 577    if (!test_ctx.decode({{seq_id, "Hello"}})) {578        GGML_ASSERT(false && "Failed to decode token");579    }580 581    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);582 583    float * logits = llama_get_sampled_logits_ith(test_ctx.ctx.get(), batch_idx);584    uint32_t n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);585 586    // Print the logits that are above the min-p threshold587    std::vector<float> filtered_logits;588    for (size_t i = 0; i < n_logits; ++i) {589        if (logits[i] > -1e9f) {590            filtered_logits.push_back(logits[i]);591            //printf("min_p logit[%zu] = %.6f\n", i, logits[i]);592        }593    }594    GGML_ASSERT(filtered_logits.size() < (size_t) test_ctx.n_vocab);595 596    // Sample using CPU sampler for verification to inspect they are reasonable597    struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();598    llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));599    llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(88));600 601    llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);602    const std::string token_str = test_ctx.token_to_piece(token, false);603    printf("min-p cpu sampled token id:%d, string: '%s'\n", token, token_str.c_str());604    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);605 606    // Decode and sample 10 more tokens607    for (int i = 0; i < 10; i++) {608        int32_t loop_idx = test_ctx.idx_for_seq(seq_id);609        llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), loop_idx);610        printf("min-p gen step %d: token id :%5.d, string: %s\n", i, token, test_ctx.token_to_piece(token, false).c_str());611        if (!test_ctx.decode_token(token, 0)) {612            GGML_ASSERT(false && "Failed to decode token");613        }614    }615 616    printf("min-p sampling test PASSED\n");617}618 619static void test_backend_top_p_sampling(const test_params & params) {620    const int seq_id = 0;621    const float p = 0.9;622    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();623    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));624    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_top_p(p, 0));625    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};626 627    test_context test_ctx(params, backend_sampler_configs);628 629    if (!test_ctx.decode({{seq_id, "Hello"}})) {630        return;631    }632 633    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);634 635    float * logits = llama_get_sampled_logits_ith(test_ctx.ctx.get(), batch_idx);636    uint32_t n_logits = llama_get_sampled_logits_count_ith(test_ctx.ctx.get(), batch_idx);637 638    // Print the logits that are above the min-p threshold639    std::vector<float> filtered_logits;640    for (size_t i = 0; i < n_logits; ++i) {641        if (logits[i] > -1e9f) {642            filtered_logits.push_back(logits[i]);643        }644    }645    GGML_ASSERT(filtered_logits.size() < (size_t) test_ctx.n_vocab);646    GGML_ASSERT(filtered_logits.size() > 0);647 648    // Sample using CPU sampler for verification to inspect they are reasonable649    struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();650    llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));651    llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(88));652 653    llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);654    const std::string token_str = test_ctx.token_to_piece(token, false);655    printf("top-p cpu sampled token id:%d, string: '%s'\n", token, token_str.c_str());656    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);657 658    // Decode and sample 10 more tokens659    for (int i = 0; i < 10; i++) {660        int32_t loop_idx = test_ctx.idx_for_seq(seq_id);661        llama_token token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), loop_idx);662        printf("top-p gen step %d: token id :%5.d, string: %s\n", i, token, test_ctx.token_to_piece(token, false).c_str());663        test_ctx.decode_token(token, 0);664    }665 666    printf("top-p sampling test PASSED\n");667}668 669static void test_backend_multi_sequence_sampling(const test_params & params) {670    struct llama_sampler_chain_params chain_params_0 = llama_sampler_chain_default_params();671    llama_sampler_ptr sampler_chain_0(llama_sampler_chain_init(chain_params_0));672    llama_sampler_chain_add(sampler_chain_0.get(), llama_sampler_init_greedy());673 674    struct llama_sampler_chain_params chain_params_1 = llama_sampler_chain_default_params();675    llama_sampler_ptr sampler_chain_1(llama_sampler_chain_init(chain_params_1));676    llama_sampler_chain_add(sampler_chain_1.get(), llama_sampler_init_temp(0.8f));677    llama_sampler_chain_add(sampler_chain_1.get(), llama_sampler_init_greedy());678 679    std::vector<llama_sampler_seq_config> backend_sampler_configs = {680        { 0, sampler_chain_0.get() },681        { 1, sampler_chain_1.get() }682    };683 684    test_context test_ctx(params, backend_sampler_configs);685 686    std::map<llama_seq_id, std::string> prompts = {687        {0, "Hello"},688        {1, "Some"}689    };690 691    if (!test_ctx.decode(prompts)) {692        GGML_ASSERT(false && "Failed to decode token");693    }694 695    // Verify sequence 0696    {697        int32_t batch_idx = test_ctx.idx_for_seq(0);698        llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), batch_idx);699        const std::string token_str = test_ctx.token_to_piece(token, false);700        printf("Seq 0 sampled token id=%d, string='%s'\n", token, token_str.c_str());701        GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);702    }703 704    // Verify sequence 1705    {706        int32_t batch_idx= test_ctx.idx_for_seq(1);707        llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), batch_idx);708        const std::string token_str = test_ctx.token_to_piece(token, false);709        printf("Seq 1 sampled token id=%d, string='%s'\n", token, token_str.c_str());710        GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);711    }712 713    // Generate tokens for each sequence714    printf("\nMulti-sequence generation:\n");715    for (int step = 0; step < 4; step++) {716        std::map<llama_seq_id, llama_token> tokens;717 718        for (llama_seq_id seq_id : {0, 1}) {719            int32_t idx = test_ctx.idx_for_seq(seq_id);720            llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), idx);721            const std::string token_str = test_ctx.token_to_piece(token, false);722            printf("  Seq %d, step %d: token id=%d, string='%s'\n", seq_id, step, token, token_str.c_str());723            tokens[seq_id] = token;724        }725 726        // Decode all tokens in a single batch727        if (!test_ctx.decode_tokens(tokens)) {728            GGML_ASSERT(false && "Failed to decode token");729        }730    }731 732    printf("backend multi-sequence sampling test PASSED\n");733}734 735static void test_backend_dist_sampling(const test_params & params) {736    const int seq_id = 0;737    const int32_t seed = 88;738 739    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();740    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));741    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_dist(seed));742    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};743 744    test_context test_ctx(params, backend_sampler_configs);745 746    if (!test_ctx.decode({{seq_id, "Some"}})) {747        GGML_ASSERT(false && "Failed to decode token");748    }749 750    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);751    llama_token token = llama_get_sampled_token_ith(test_ctx.ctx.get(), batch_idx);752    printf("dist sampled id:%d, string:'%s'\n", token, test_ctx.token_to_piece(token, false).c_str());753    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);754    //GGML_ASSERT(llama_get_sampled_logits_ith(test_ctx.ctx.get(), batch_idx) == nullptr);755 756    token = llama_get_sampled_token_ith(test_ctx.ctx.get(), -1);757    printf("dist sampled id:%d, string:'%s'\n", token, test_ctx.token_to_piece(token, false).c_str());758    GGML_ASSERT(token >= 0 && token < test_ctx.n_vocab);759 760    printf("backend dist sampling test PASSED\n");761}762 763static void test_backend_dist_sampling_and_cpu(const test_params & params) {764    const int seq_id = 0;765    const int32_t seed = 88;766 767    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();768    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));769    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_dist(seed));770    std::vector<llama_sampler_seq_config> backend_sampler_configs = {{ seq_id, backend_sampler_chain.get() }};771 772    test_context test_ctx(params, backend_sampler_configs);773 774    if (!test_ctx.decode({{seq_id, "Some"}})) {775        GGML_ASSERT(false && "Failed to decode token");776    }777 778    int32_t batch_idx = test_ctx.idx_for_seq(seq_id);779 780    // Sample using CPU sampler781    struct llama_sampler_chain_params chain_params = llama_sampler_chain_default_params();782    llama_sampler_ptr chain(llama_sampler_chain_init(chain_params));783    llama_sampler_chain_add(chain.get(), llama_sampler_init_dist(18));784 785    llama_token backend_token = llama_get_sampled_token_ith(test_ctx.ctx.get(), batch_idx);786    llama_token cpu_token = llama_sampler_sample(chain.get(), test_ctx.ctx.get(), batch_idx);787    printf("dist & cpu sampled id:%d, string:'%s'\n", cpu_token, test_ctx.token_to_piece(cpu_token, false).c_str());788    GGML_ASSERT(backend_token == cpu_token);789 790    printf("backend dist & cpu sampling test PASSED\n");791}792 793static void test_backend_logit_bias_sampling(const test_params & params) {794    const auto * model = params.model.get();795    const auto * vocab = llama_model_get_vocab(model);796 797    const int seq_id = 0;798 799    std::vector<llama_logit_bias> logit_bias;800 801    // Get the token for the piece "World".802    const std::string piece = "World";803    std::vector<llama_token> tokens(16);804    llama_tokenize(vocab, piece.c_str(), piece.size(), tokens.data(), tokens.size(), false, false);805 806    llama_token bias_token = tokens[0];807    // TODO: biasing too much here makes the Vulkan sampling fail - should be investigated further808    //       https://github.com/ggml-org/llama.cpp/actions/runs/20894267644/job/60030252675?pr=18753#step:3:23350809    //logit_bias.push_back({ bias_token, +100.0f });810    logit_bias.push_back({ bias_token, +10.0f });811 812    printf("biasing token piece '%s' -> token id %d\n", piece.c_str(), bias_token);813 814    struct llama_sampler_chain_params backend_chain_params = llama_sampler_chain_default_params();815    llama_sampler_ptr backend_sampler_chain(llama_sampler_chain_init(backend_chain_params));816    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_logit_bias(817                llama_vocab_n_tokens(vocab),818                logit_bias.size(),819                logit_bias.data()));820    llama_sampler_chain_add(backend_sampler_chain.get(), llama_sampler_init_dist(88));821 822    std::vector<llama_sampler_seq_config> backend_sampler_configs = {823        { seq_id, backend_sampler_chain.get() },824    };825 826    test_context test_ctx(params, backend_sampler_configs);827 828    if (!test_ctx.decode({{seq_id, "Hello"}})) {829        GGML_ASSERT(false && "Failed to decode token");830    }831 832    llama_token backend_token = llama_get_sampled_token_ith(test_ctx.ctx.get(), test_ctx.idx_for_seq(seq_id));833    printf("sampled token = %d, expected = %d\n", backend_token, bias_token);834    GGML_ASSERT(backend_token == bias_token);835 836    printf("backend logit bias sampling test PASSED\n");837}838 839static void accept_prompt(llama_sampler * smpl, const llama_vocab * vocab, const std::string & prompt) {840    const llama_token bos = llama_vocab_bos(vocab);841    if (bos != LLAMA_TOKEN_NULL) {842        llama_sampler_accept(smpl, bos);843    }844 845    std::vector<llama_token> tokens(64);846    int32_t n_tokens = llama_tokenize(vocab, prompt.c_str(), (int32_t) prompt.size(),847            tokens.data(), (int32_t) tokens.size(), false, false);848    if (n_tokens < 0) {849        tokens.resize(-n_tokens);850        n_tokens = llama_tokenize(vocab, prompt.c_str(), (int32_t) prompt.size(),851                tokens.data(), (int32_t) tokens.size(), false, false);852    }853 854    for (int32_t i = 0; i < n_tokens; ++i) {855        llama_sampler_accept(smpl, tokens[i]);856    }857}858 859static std::vector<float> decode_raw_logits(const test_params & params, const std::string & prompt) {860    const int seq_id = 0;861    const int n_vocab = llama_vocab_n_tokens(llama_model_get_vocab(params.model.get()));862    std::vector<llama_sampler_seq_config> empty_configs;863    test_context ctx(params, empty_configs);864 865    GGML_ASSERT(ctx.decode({{ seq_id, prompt }}));866 867    float * logits = llama_get_logits_ith(ctx.ctx.get(), ctx.idx_for_seq(seq_id));868    GGML_ASSERT(logits != nullptr);869    return std::vector<float>(logits, logits + n_vocab);870}871 872static std::vector<llama_token_data> apply_cpu_sampler(873        const std::vector<float> & raw_logits,874        llama_sampler * sampler) {875    std::vector<llama_token_data> data;876    data.reserve(raw_logits.size());877    for (llama_token token = 0; token < (llama_token) raw_logits.size(); ++token) {878        data.push_back({ token, raw_logits[token], 0.0f });879    }880 881    llama_token_data_array cur_p = { data.data(), data.size(), -1, false };882    llama_sampler_apply(sampler, &cur_p);883    data.resize(cur_p.size);884    return data;885}886 887using sampler_setup_fn = std::function<void(llama_sampler *)>;888using sampler_init_fn = std::function<llama_sampler *()>;889 890enum class penalties_position {891    before_filter,892    after_filter,893};894 895static void add_filter_and_penalties(896        llama_sampler * chain,897        const sampler_init_fn & init_filter,898        int32_t n_vocab,899        int32_t penalty_last_n,900        float penalty_repeat,901        float penalty_freq,902        float penalty_present,903        penalties_position position) {904    const auto add_penalties = [&]() {905        llama_sampler_chain_add(chain, llama_sampler_init_penalties(906                    n_vocab, penalty_last_n, penalty_repeat, penalty_freq, penalty_present));907    };908 909    if (position == penalties_position::before_filter) {910        add_penalties();911        llama_sampler_chain_add(chain, init_filter());912    } else {913        llama_sampler_chain_add(chain, init_filter());914        add_penalties();915    }916}917 918static llama_sampler_ptr make_sampler_chain(919        const sampler_setup_fn & add_samplers,920        const sampler_setup_fn & accept_history) {921    llama_sampler_ptr chain(llama_sampler_chain_init(llama_sampler_chain_default_params()));922    add_samplers(chain.get());923    accept_history(chain.get());924    return chain;925}926 927struct backend_sampler_output {928    std::vector<float> logits;929    std::vector<llama_token> candidates;930};931 932static backend_sampler_output run_backend_sampler(933        const test_params & params,934        const std::string & prompt,935        llama_sampler * sampler) {936    const int seq_id = 0;937    std::vector<llama_sampler_seq_config> configs = {{ seq_id, sampler }};938    test_context ctx(params, configs);939 940    GGML_ASSERT(ctx.decode({{ seq_id, prompt }}));941    llama_synchronize(ctx.ctx.get());942 943    const int32_t idx = ctx.idx_for_seq(seq_id);944    const uint32_t n_logits = llama_get_sampled_logits_count_ith(ctx.ctx.get(), idx);945    const uint32_t n_candidates = llama_get_sampled_candidates_count_ith(ctx.ctx.get(), idx);946    float * logits = llama_get_sampled_logits_ith(ctx.ctx.get(), idx);947    llama_token * candidates = llama_get_sampled_candidates_ith(ctx.ctx.get(), idx);948    GGML_ASSERT(logits != nullptr);949 950    backend_sampler_output result;951    result.logits.assign(logits, logits + n_logits);952    result.candidates.resize(n_logits);953 954    if (n_candidates == 0) {955        for (uint32_t i = 0; i < n_logits; ++i) {956            result.candidates[i] = (llama_token) i;957        }958    } else {959        GGML_ASSERT(candidates != nullptr);960        GGML_ASSERT(n_candidates == n_logits);961        std::memcpy(result.candidates.data(), candidates, n_candidates * sizeof(llama_token));962    }963 964    return result;965}966 967struct sampler_comparison_output {968    std::vector<llama_token_data> expected;969    backend_sampler_output actual;970};971 972static sampler_comparison_output run_sampler_comparison(973        const test_params & params,974        const std::string & prompt,975        const std::vector<float> & raw_logits,976        const sampler_setup_fn & add_samplers,977        const sampler_setup_fn & accept_history) {978    llama_sampler_ptr cpu_chain = make_sampler_chain(add_samplers, accept_history);979    llama_sampler_ptr backend_chain = make_sampler_chain(add_samplers, accept_history);980    return {981        apply_cpu_sampler(raw_logits, cpu_chain.get()),982        run_backend_sampler(params, prompt, backend_chain.get()),983    };984}985 986static std::unordered_map<llama_token, float> map_logits(const std::vector<llama_token_data> & data) {987    std::unordered_map<llama_token, float> result;988    result.reserve(data.size());989    for (const auto & item : data) {990        result[item.id] = item.logit;991    }992    return result;993}994 995struct sampler_comparison_stats {996    int n_mismatch = 0;997    int n_masked = 0;998    float max_diff = 0.0f;999};1000 1001static sampler_comparison_stats compare_sampler_outputs(1002        const char * name,1003        const std::unordered_map<llama_token, float> & expected,1004        const backend_sampler_output & actual,1005        bool allow_extra_candidates = false) {1006    GGML_ASSERT(actual.logits.size() == actual.candidates.size());1007 1008    sampler_comparison_stats result;1009    std::unordered_set<llama_token> seen;1010    seen.reserve(actual.candidates.size());1011 1012    for (size_t i = 0; i < actual.logits.size(); ++i) {1013        const llama_token token = actual.candidates[i];1014        const float logit = actual.logits[i];1015        if (!seen.insert(token).second || std::isnan(logit)) {1016            if (result.n_mismatch < 5) {1017                printf("%s token %d has invalid backend output\n", name, token);1018            }1019            ++result.n_mismatch;1020            continue;1021        }1022 1023        const auto it = expected.find(token);1024        if (it == expected.end()) {1025            if (std::isinf(logit) && logit < 0.0f) {1026                ++result.n_masked;1027            } else if (!allow_extra_candidates) {1028                if (result.n_mismatch < 5) {1029                    printf("%s token %d was not masked\n", name, token);1030                }1031                ++result.n_mismatch;1032            }1033            continue;1034        }1035 1036        const float diff = fabsf(it->second - logit);1037        result.max_diff = std::max(result.max_diff, diff);1038        if (!std::isfinite(logit) || diff > 1e-3f) {1039            if (result.n_mismatch < 5) {1040                printf("%s mismatch token %d: cpu=%.6f backend=%.6f diff=%.6f\n",1041                        name, token, it->second, logit, diff);1042            }1043            ++result.n_mismatch;1044        }1045    }1046 1047    for (const auto & item : expected) {1048        if (seen.find(item.first) == seen.end()) {1049            if (result.n_mismatch < 5) {1050                printf("%s missing backend token %d\n", name, item.first);1051            }1052            ++result.n_mismatch;1053        }1054    }1055 1056    printf("%s logits: max_diff=%.6f n_masked=%d n_mismatch=%d\n",1057            name, result.max_diff, result.n_masked, result.n_mismatch);1058    return result;1059}1060 1061static float find_backend_logit(const backend_sampler_output & output, llama_token token) {1062    for (size_t i = 0; i < output.candidates.size(); ++i) {1063        if (output.candidates[i] == token) {1064            return output.logits[i];1065        }1066    }1067    GGML_ABORT("backend token not found");1068}1069 1070static sampler_comparison_output run_penalties_comparison(1071        const test_params & params,1072        int32_t penalty_last_n,1073        float penalty_repeat,1074        float penalty_freq,1075        float penalty_present,1076        const std::string & prompt,1077        const std::function<void(llama_sampler *)> & extra_accept = {}) {1078    const auto * vocab = llama_model_get_vocab(params.model.get());1079    const std::vector<float> raw_logits = decode_raw_logits(params, prompt);1080    const auto add_samplers = [&](llama_sampler * chain) {1081        llama_sampler_chain_add(chain, llama_sampler_init_penalties(1082                    llama_vocab_n_tokens(vocab), penalty_last_n, penalty_repeat, penalty_freq, penalty_present));1083    };1084    const auto accept_history = [&](llama_sampler * chain) {1085        accept_prompt(chain, vocab, prompt);1086        if (extra_accept) {1087            extra_accept(chain);1088        }1089    };1090 1091    return run_sampler_comparison(1092            params, prompt, raw_logits, add_samplers, accept_history);1093}1094 1095static void compare_penalties_logits(1096        const test_params & params,1097        int32_t penalty_last_n,1098        float penalty_repeat,1099        float penalty_freq,1100        float penalty_present,1101        const std::string & prompt,1102        const std::function<void(llama_sampler *)> & extra_accept = {}) {1103    const sampler_comparison_output output = run_penalties_comparison(1104            params, penalty_last_n, penalty_repeat, penalty_freq, penalty_present, prompt, extra_accept);1105 1106    GGML_ASSERT(output.expected.size() == output.actual.logits.size());1107 1108    const sampler_comparison_stats stats = compare_sampler_outputs(1109            "penalties", map_logits(output.expected), output.actual);1110    GGML_ASSERT(stats.n_masked == 0);1111    GGML_ASSERT(stats.n_mismatch == 0);1112}1113 1114static void test_penalty_parameter_values(const test_params & params) {1115    struct penalty_test_case {1116        const char * name;1117        float repeat;1118        float frequency;1119        float presence;1120    };1121 1122    const penalty_test_case cases[] = {1123        { "frequency -1",   1.0f, -1.0f,     0.0f },1124        { "frequency 0",    1.0f,  0.0f,     0.0f },1125        { "frequency 1",    1.0f,  1.0f,     0.0f },1126        { "presence -1",    1.0f,  0.0f,    -1.0f },1127        { "presence 0",     1.0f,  0.0f,     0.0f },1128        { "presence 1",     1.0f,  0.0f,     1.0f },1129        { "repeat 1",       1.0f,  0.0f,     0.0f },1130    };1131 1132    int n_failed = 0;1133    for (const auto & test : cases) {1134        const sampler_comparison_output output = run_penalties_comparison(1135                params, 64, test.repeat, test.frequency, test.presence, "Hello Hello world");1136        GGML_ASSERT(output.expected.size() == output.actual.logits.size());1137        const sampler_comparison_stats stats = compare_sampler_outputs(1138                test.name, map_logits(output.expected), output.actual);1139        n_failed += stats.n_mismatch != 0;1140    }1141 1142    GGML_ASSERT(n_failed == 0);1143}1144 1145static void compare_top_k_penalties_logits(1146        const test_params & params,1147        int32_t k,1148        int32_t penalty_last_n,1149        float penalty_repeat,1150        float penalty_freq,1151        float penalty_present,1152        const std::string & prompt,1153        penalties_position position) {1154    const auto * vocab = llama_model_get_vocab(params.model.get());1155    const std::vector<float> raw_logits = decode_raw_logits(params, prompt);1156    const int n_vocab = (int) raw_logits.size();1157 1158    GGML_ASSERT(n_vocab > k);1159 1160    const sampler_init_fn init_top_k = [k]() {1161        return llama_sampler_init_top_k(k);1162    };1163    llama_sampler_ptr top_k(init_top_k());1164    const std::vector<llama_token_data> top_k_data = apply_cpu_sampler(raw_logits, top_k.get());1165    GGML_ASSERT(top_k_data.size() == (size_t) k);1166    const llama_token retained_history_token = top_k_data[0].id;1167 1168    llama_token excluded_history_token = LLAMA_TOKEN_NULL;1169    for (llama_token token = 0; token < n_vocab; ++token) {1170        const auto it = std::find_if(top_k_data.begin(), top_k_data.end(), [token](const llama_token_data & data) {1171            return data.id == token;1172        });1173        if (it == top_k_data.end()) {1174            excluded_history_token = token;1175            break;1176        }1177    }1178    GGML_ASSERT(excluded_history_token != LLAMA_TOKEN_NULL);1179 1180    const auto add_samplers = [&](llama_sampler * chain) {1181        add_filter_and_penalties(chain, init_top_k, n_vocab,1182                penalty_last_n, penalty_repeat, penalty_freq, penalty_present, position);1183    };1184 1185    auto accept_history = [&](llama_sampler * smpl) {1186        accept_prompt(smpl, vocab, prompt);1187        llama_sampler_accept(smpl, excluded_history_token);1188        llama_sampler_accept(smpl, excluded_history_token);1189        llama_sampler_accept(smpl, retained_history_token);1190        llama_sampler_accept(smpl, retained_history_token);1191    };1192 1193    const sampler_comparison_output output = run_sampler_comparison(1194            params, prompt, raw_logits, add_samplers, accept_history);1195 1196    GGML_ASSERT(output.expected.size() == (size_t) k);1197    GGML_ASSERT(output.actual.logits.size() == (size_t) k);1198 1199    const std::unordered_map<llama_token, float> expected_logits = map_logits(output.expected);1200 

Showing the first 1,200 of 2168 lines. Download the file for the rest.