char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

linsen458-specllama : use int32_t for llama_sampler_chain_n return type (#28631)4850c7727

char/aliceai-t5-moe
148.2 KiB4385 linesraw
1#include "llama-sampler.h"
2
3#include "llama-impl.h"
4#include "llama-vocab.h"
5#include "llama-grammar.h"
6
7#include "ggml-cpp.h"
8
9#include <array>
10#include <algorithm>
11#include <cassert>
12#include <cfloat>
13#include <chrono>
14#include <cmath>
15#include <cstdlib>
16#include <cstring>
17#include <ctime>
18#include <numeric>
19#include <random>
20#include <unordered_map>
21#include <stdexcept>
22
23// the ring buffer works similarly to std::deque, but with a fixed capacity
24template<typename T>
25struct ring_buffer {
26    ring_buffer(size_t cap) : capacity(cap), data(cap) {}
27
28    T & front() {
29        if (sz == 0) {
30            throw std::runtime_error("ring buffer is empty");
31        }
32        return data[first];
33    }
34
35    const T & front() const {
36        if (sz == 0) {
37            throw std::runtime_error("ring buffer is empty");
38        }
39        return data[first];
40    }
41
42    T & back() {
43        if (sz == 0) {
44            throw std::runtime_error("ring buffer is empty");
45        }
46        return data[pos];
47    }
48
49    const T & back() const {
50        if (sz == 0) {
51            throw std::runtime_error("ring buffer is empty");
52        }
53        return data[pos];
54    }
55
56    void push_back(const T & value) {
57        if (capacity == 0) {
58            throw std::runtime_error("ring buffer: capacity is zero");
59        }
60
61        if (sz == capacity) {
62            // advance the start when buffer is full
63            first = (first + 1) % capacity;
64        } else {
65            sz++;
66        }
67        data[pos] = value;
68        pos = (pos + 1) % capacity;
69    }
70
71    T pop_front() {
72        if (sz == 0) {
73            throw std::runtime_error("ring buffer is empty");
74        }
75        T value = data[first];
76        first = (first + 1) % capacity;
77        sz--;
78        return value;
79    }
80
81    //T & operator[](size_t i) {
82    //    if (i >= sz) {
83    //        throw std::runtime_error("ring buffer: index out of bounds");
84    //    }
85    //    return data[(first + i) % capacity];
86    //}
87
88    //const T & at(size_t i) const {
89    //    if (i >= sz) {
90    //        throw std::runtime_error("ring buffer: index out of bounds");
91    //    }
92    //    return data[(first + i) % capacity];
93    //}
94
95    const T & rat(size_t i) const {
96        if (i >= sz) {
97            throw std::runtime_error("ring buffer: index out of bounds");
98        }
99        return data[(first + sz - i - 1) % capacity];
100    }
101
102    std::vector<T> to_vector() const {
103        std::vector<T> result;
104        result.reserve(sz);
105        for (size_t i = 0; i < sz; i++) {
106            result.push_back(data[(first + i) % capacity]);
107        }
108        return result;
109    }
110
111    void clear() {
112        // here only reset the status of the buffer
113        sz = 0;
114        first = 0;
115        pos = 0;
116    }
117
118    bool empty() const {
119        return sz == 0;
120    }
121
122    size_t size() const {
123        return sz;
124    }
125
126    size_t capacity = 0;
127    size_t sz = 0;
128    size_t first = 0;
129    size_t pos = 0;
130
131    std::vector<T> data;
132};
133
134// writes result in res, does not mutate cur
135static void llama_token_data_array_partial_sort(const llama_token_data_array & cur, int npartial, std::vector<llama_token_data> & res) {
136    static const auto comp = [](const llama_token_data & a, const llama_token_data & b) {
137        return a.logit > b.logit;
138    };
139
140    constexpr int   nbuckets     = 128;
141    constexpr float bucket_low   = -10.0f;
142    constexpr float bucket_high  =  10.0f;
143    constexpr float bucket_scale = nbuckets/(bucket_high - bucket_low);
144    constexpr float bucket_inter = -bucket_low * bucket_scale;
145
146    std::vector<int> bucket_idx;
147    std::vector<int> histo(nbuckets, 0);
148
149    std::vector<llama_token_data*> bucket_ptrs;
150
151    bucket_idx.reserve(cur.size);
152
153    for (int i = 0; i < (int)cur.size; ++i) {
154        const float val = cur.data[i].logit;
155        int ib = int(bucket_scale * val + bucket_inter); //nbuckets * (val - bucket_low) / (bucket_high - bucket_low);
156        ib = std::max(0, std::min(nbuckets - 1, ib));
157        bucket_idx.push_back(ib);
158        ++histo[ib];
159    }
160    int nhave = 0;
161    int ib = nbuckets - 1;
162    for ( ; ib >= 0; --ib) {
163        nhave += histo[ib];
164        if (nhave >= npartial) {
165            break;
166        }
167    }
168    res.resize(nhave);
169    auto * ptr = res.data();
170    bucket_ptrs.reserve(nbuckets - ib);
171    for (int j = nbuckets - 1; j >= ib; --j) {
172        bucket_ptrs.push_back(ptr);
173        ptr += histo[j];
174    }
175    for (int i = 0; i < (int)cur.size; ++i) {
176        int j = bucket_idx[i];
177        if (j >= ib) {
178            *bucket_ptrs[nbuckets - 1 - j]++ = cur.data[i];
179        }
180    }
181
182    ptr = res.data();
183    int ndone = 0;
184    for (int j = nbuckets - 1; j > ib; --j) {
185        std::sort(ptr, ptr + histo[j], comp);
186        ptr += histo[j];
187        ndone += histo[j];
188    }
189    std::partial_sort(ptr, ptr + npartial - ndone, ptr + histo[ib], comp);
190}
191
192// reduces the size of cur_p to npartial, keeping only the top npartial elements
193static void llama_token_data_array_partial_sort_inplace(llama_token_data_array * cur_p, int npartial) {
194    static const auto comp = [](const llama_token_data & a, const llama_token_data & b) {
195        return a.logit > b.logit;
196    };
197
198    if (npartial <= 128) {
199        std::partial_sort(cur_p->data, cur_p->data + npartial, cur_p->data + cur_p->size, comp);
200
201        cur_p->size = npartial;
202        cur_p->sorted = true;
203
204        return;
205    }
206
207    std::vector<llama_token_data> tmp;
208
209    llama_token_data_array_partial_sort(*cur_p, npartial, tmp);
210
211    std::copy(tmp.data(), tmp.data() + npartial, cur_p->data);
212
213    cur_p->size = npartial;
214    cur_p->sorted = true;
215}
216
217static int llama_sample_dist(llama_token_data_array * cur_p, std::mt19937 & rng) {
218    // iterator for the probabilities
219#ifdef __GNUC__
220    #pragma GCC diagnostic push
221    #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
222#endif
223
224    struct probs_iterator {
225        typedef std::input_iterator_tag iterator_category;
226        typedef float value_type;
227        typedef float * pointer;
228        typedef float & reference;
229        typedef ptrdiff_t difference_type;
230
231        const llama_token_data * data;
232
233        bool operator==(const probs_iterator & other) const { return data == other.data; }
234        bool operator!=(const probs_iterator & other) const { return data != other.data; }
235        const float & operator*() const { return data->p; }
236        probs_iterator & operator++() { ++data; return *this; }
237        probs_iterator operator++(int) { probs_iterator tmp = *this; ++data; return tmp; }
238    };
239
240#ifdef __GNUC__
241    #pragma GCC diagnostic pop
242#endif
243
244    std::discrete_distribution<int> dist(probs_iterator{cur_p->data}, probs_iterator{cur_p->data + cur_p->size});
245
246    return dist(rng);
247}
248
249/*
250static void llama_log_softmax(float * array, size_t size) {
251    float max_l = *std::max_element(array, array + size);
252    float sum = 0.f;
253    for (size_t i = 0; i < size; ++i) {
254        float p = expf(array[i] - max_l);
255        sum += p;
256        array[i] = p;
257    }
258
259    for (size_t i = 0; i < size; ++i) {
260        array[i] = logf(array[i] / sum);
261    }
262}
263*/
264
265static void llama_sampler_temp_impl(llama_token_data_array * cur_p, float temp) {
266    if (cur_p->size == 0) {
267        return;
268    }
269
270    if (temp <= 0.0f) {
271        // find the token with the highest logit and set the rest to -inf
272        size_t max_i = 0;
273        float  max_l = cur_p->data[0].logit;
274
275        for (size_t i = 1; i < cur_p->size; ++i) {
276            if (cur_p->data[i    ].logit > max_l) {
277                cur_p->data[max_i].logit = -INFINITY;
278                max_i = i;
279                max_l = cur_p->data[i].logit;
280            } else {
281                cur_p->data[i].logit = -INFINITY;
282            }
283        }
284
285        return;
286    }
287
288    for (size_t i = 0; i < cur_p->size; ++i) {
289        cur_p->data[i].logit /= temp;
290    }
291}
292
293static void llama_sampler_softmax_impl(llama_token_data_array * cur_p, bool do_sort) {
294    GGML_ASSERT(cur_p->size > 0);
295
296    // Sort the logits in descending order if requested
297    if (do_sort && !cur_p->sorted) {
298        llama_token_data_array_partial_sort_inplace(cur_p, cur_p->size);
299    }
300
301    float max_l = cur_p->data[0].logit;
302    if (!cur_p->sorted) {
303        for (size_t i = 1; i < cur_p->size; ++i) {
304            max_l = std::max(max_l, cur_p->data[i].logit);
305        }
306    }
307
308    float cum_sum = 0.0f;
309
310    for (size_t i = 0; i < cur_p->size; ++i) {
311        float p = expf(cur_p->data[i].logit - max_l);
312        cur_p->data[i].p = p;
313        cum_sum += p;
314    }
315
316    for (size_t i = 0; i < cur_p->size; ++i) {
317        cur_p->data[i].p /= cum_sum;
318    }
319}
320
321static void llama_sampler_top_k_impl(llama_token_data_array * cur_p, int32_t k) {
322    // if (k >= (int32_t)cur_p->size) {
323    //     return;
324    // }
325
326    if (k <= 0) {
327        return;
328    }
329
330    k = std::min(k, (int) cur_p->size);
331
332    // Sort scores in descending order
333    if (!cur_p->sorted) {
334        llama_token_data_array_partial_sort_inplace(cur_p, k);
335    }
336
337    cur_p->size = k;
338}
339
340static uint32_t get_rng_seed(uint32_t seed) {
341    if (seed == LLAMA_DEFAULT_SEED) {
342        // use system clock if std::random_device is not a true RNG
343        static bool is_rd_prng = std::random_device().entropy() == 0;
344        if (is_rd_prng) {
345            return (uint32_t) std::chrono::system_clock::now().time_since_epoch().count();
346        }
347        std::random_device rd;
348        return rd();
349    }
350    return seed;
351}
352
353// llama_sampler API
354
355struct llama_sampler * llama_sampler_init(
356        struct llama_sampler_i * iface,
357        llama_sampler_context_t ctx) {
358    return new llama_sampler {
359        /* .iface = */ iface,
360        /* .ctx   = */ ctx,
361    };
362}
363
364const char * llama_sampler_name(const struct llama_sampler * smpl) {
365    if (!smpl->iface) {
366        return "(null)";
367    }
368
369    return smpl->iface->name(smpl);
370}
371
372void llama_sampler_accept(struct llama_sampler * smpl, llama_token token) {
373    if (!smpl) {
374        return;
375    }
376
377    if (smpl->iface->accept) {
378        smpl->iface->accept(smpl, token);
379    }
380}
381
382void llama_sampler_apply(struct llama_sampler * smpl, struct llama_token_data_array * cur_p) {
383    if (!smpl) {
384        return;
385    }
386
387    GGML_ASSERT(smpl->iface->apply);
388    smpl->iface->apply(smpl, cur_p);
389}
390
391void llama_sampler_reset(struct llama_sampler * smpl) {
392    if (!smpl) {
393        return;
394    }
395
396    if (smpl->iface->reset) {
397        smpl->iface->reset(smpl);
398    }
399}
400
401struct llama_sampler * llama_sampler_clone(const struct llama_sampler * smpl) {
402    if (!smpl) {
403        return nullptr;
404    }
405
406    if (smpl->iface->clone) {
407        return smpl->iface->clone(smpl);
408    }
409
410    if (smpl->ctx == nullptr) {
411        return llama_sampler_init(
412            /* .iface = */ smpl->iface,
413            /* .ctx   = */ nullptr
414        );
415    }
416
417    GGML_ABORT("the sampler does not support cloning");
418}
419
420void llama_sampler_free(struct llama_sampler * smpl) {
421    if (smpl == nullptr) {
422        return;
423    }
424
425    if (smpl->iface->free) {
426        smpl->iface->free(smpl);
427    }
428
429    delete smpl;
430}
431
432// empty sampler
433
434struct llama_sampler_empty {
435    const char * name;
436};
437
438static struct llama_sampler * llama_sampler_init_empty(const char * name);
439
440static const char * llama_sampler_empty_name(const struct llama_sampler * smpl) {
441    auto * ctx = (llama_sampler_empty *) smpl->ctx;
442    return ctx->name;
443}
444
445static void llama_sampler_empty_accept(struct llama_sampler * smpl, llama_token token) {
446    GGML_UNUSED(smpl);
447    GGML_UNUSED(token);
448}
449
450static void llama_sampler_empty_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
451    GGML_UNUSED(smpl);
452    GGML_UNUSED(cur_p);
453}
454
455static void llama_sampler_empty_reset(struct llama_sampler * smpl) {
456    GGML_UNUSED(smpl);
457}
458
459static struct llama_sampler * llama_sampler_empty_clone(const struct llama_sampler * smpl) {
460    auto * ctx = (llama_sampler_empty *) smpl->ctx;
461    return llama_sampler_init_empty(ctx->name);
462}
463
464static void llama_sampler_empty_free(struct llama_sampler * smpl) {
465    delete (llama_sampler_empty *) smpl->ctx;
466}
467
468static bool llama_sampler_empty_backend_init(
469        struct llama_sampler       * smpl,
470        ggml_backend_buffer_type_t   buft,
471        uint32_t                     n_outputs_max_per_seq) {
472    GGML_UNUSED(smpl);
473    GGML_UNUSED(buft);
474    GGML_UNUSED(n_outputs_max_per_seq);
475
476    return true;
477}
478
479static void llama_sampler_empty_backend_accept(
480        struct llama_sampler * smpl,
481        ggml_context * ctx,
482        ggml_cgraph * gf,
483        struct ggml_tensor * selected_token) {
484    GGML_UNUSED(smpl);
485    GGML_UNUSED(ctx);
486    GGML_UNUSED(gf);
487    GGML_UNUSED(selected_token);
488}
489
490static void llama_sampler_empty_backend_apply(
491          struct llama_sampler      * smpl,
492          struct ggml_context       * ctx,
493          struct ggml_cgraph        * gf,
494          struct llama_sampler_data * data) {
495    GGML_UNUSED(smpl);
496    GGML_UNUSED(ctx);
497    GGML_UNUSED(gf);
498    GGML_UNUSED(data);
499}
500
501static void llama_sampler_empty_backend_set_input(struct llama_sampler * smpl) {
502    GGML_UNUSED(smpl);
503}
504
505static struct llama_sampler_i llama_sampler_empty_i = {
506    /* .name              = */ llama_sampler_empty_name,
507    /* .accept            = */ llama_sampler_empty_accept,
508    /* .apply             = */ llama_sampler_empty_apply,
509    /* .reset             = */ llama_sampler_empty_reset,
510    /* .clone             = */ llama_sampler_empty_clone,
511    /* .free              = */ llama_sampler_empty_free,
512    /* .backend_init      = */ llama_sampler_empty_backend_init,
513    /* .backend_accept    = */ llama_sampler_empty_backend_accept,
514    /* .backend_apply     = */ llama_sampler_empty_backend_apply,
515    /* .backend_set_input = */ llama_sampler_empty_backend_set_input,
516    /* .backend_reset     = */ nullptr,
517    /* .copy_state        = */ nullptr,
518};
519
520struct llama_sampler * llama_sampler_init_empty(const char * name) {
521    return llama_sampler_init(
522        /* .iface = */ &llama_sampler_empty_i,
523        /* .ctx   = */ new llama_sampler_empty {
524            /* .name = */ name,
525        }
526    );
527}
528
529// common backend sampler functionality
530//
531// +name : means that the sampler is support and will run on the backend
532// -name : means that a ggml operator is not supported by the backend
533//
534struct llama_sampler_backend {
535    llama_sampler_backend(const char * name) : name(name), name_ext(name), is_init(false), support(false) {}
536
537    const char * get_name() {
538        if (!is_init) {
539            return name.c_str();
540        }
541
542        if (support) {
543            name_ext = "+" + name;
544        } else {
545            name_ext = "-" + name;
546        }
547
548        return name_ext.c_str();
549    }
550
551    void init(bool support) {
552        GGML_ASSERT(this->is_init == false);
553
554        this->is_init = true;
555        this->support = support;
556    }
557
558    // copy the state that is not tied to the current sampling graph
559    // samplers that hold only immutable configuration can use this as is
560    void copy_state(const llama_sampler_backend & src) {
561        GGML_UNUSED(src);
562    }
563
564private:
565    std::string name;
566    std::string name_ext;
567
568    bool is_init;
569    bool support;
570};
571
572// .copy_state for samplers deriving from llama_sampler_backend
573template<typename T>
574static void llama_sampler_backend_copy_state(const struct llama_sampler * src, struct llama_sampler * dst) {
575    ((T *) dst->ctx)->copy_state(*(const T *) src->ctx);
576}
577
578struct llama_sampler_backend_probe {
579    ggml_context_ptr ctx;
580    ggml_cgraph * gf;
581};
582
583static llama_sampler_backend_probe llama_sampler_backend_probe_graph(
584        llama_sampler * sampler,
585        int64_t         n_candidates,
586        uint32_t        max_nodes,
587        bool            with_candidates) {
588    ggml_init_params params = {
589        /*.mem_size   =*/ max_nodes * ggml_tensor_overhead() + ggml_graph_overhead_custom(max_nodes, false),
590        /*.mem_buffer =*/ nullptr,
591        /*.no_alloc   =*/ true,
592    };
593
594    ggml_context_ptr ctx_ptr { ggml_init(params) };
595    if (!ctx_ptr) {
596        throw std::runtime_error(format("failed to create ggml context"));
597    }
598
599    auto * ctx = ctx_ptr.get();
600    auto * gf = ggml_new_graph_custom(ctx, max_nodes, false);
601
602    llama_sampler_data data = {
603        /*.logits       =*/ ggml_new_tensor_1d(ctx, GGML_TYPE_F32, n_candidates),
604        /*.probs        =*/ nullptr,
605        /*.sampled      =*/ nullptr,
606        /*.candidates   =*/ with_candidates ? ggml_new_tensor_1d(ctx, GGML_TYPE_I32, n_candidates) : nullptr,
607    };
608
609    if (sampler->iface->backend_reset) {
610        sampler->iface->backend_reset(sampler);
611    }
612    sampler->iface->backend_apply(sampler, ctx, gf, &data);
613
614    for (auto * output : { data.logits, data.probs, data.sampled, data.candidates }) {
615        if (output) {
616            ggml_build_forward_expand(gf, output);
617        }
618    }
619
620    if (sampler->iface->backend_reset) {
621        sampler->iface->backend_reset(sampler);
622    }
623
624    return { std::move(ctx_ptr), gf };
625}
626
627static uint32_t llama_sampler_backend_probe_n_nodes(const llama_sampler_backend_probe & probe) {
628    uint32_t n_tensors = 0;
629    for (auto * tensor = ggml_get_first_tensor(probe.ctx.get()); tensor;
630            tensor = ggml_get_next_tensor(probe.ctx.get(), tensor)) {
631        ++n_tensors;
632    }
633
634    return std::max<uint32_t>(ggml_graph_n_nodes(probe.gf), n_tensors);
635}
636
637// check if all ggml ops used by the sampler are supported by the backend
638static bool llama_sampler_backend_support(
639        llama_sampler              * smpl,
640        ggml_backend_buffer_type_t   buft) {
641    auto * device = ggml_backend_buft_get_device(buft);
642    if (!device) {
643        // CPU backend always supported
644        return true;
645    }
646
647    auto probe = llama_sampler_backend_probe_graph(smpl, 1024*1024, GGML_DEFAULT_GRAPH_SIZE, true);
648
649    for (int i = 0; i < ggml_graph_n_nodes(probe.gf); i++) {
650        struct ggml_tensor * op = ggml_graph_node(probe.gf, i);
651
652        if (!ggml_backend_dev_supports_op(device, op)) {
653            LLAMA_LOG_WARN("%s: device '%s' does not have support for op %s needed for sampler '%s'\n",
654                    __func__, ggml_backend_dev_name(device), ggml_op_name(op->op), smpl->iface->name(smpl));
655
656            return false;
657        }
658    }
659
660    return true;
661}
662
663// sampler chain
664
665static const char * llama_sampler_chain_name(const struct llama_sampler * /*smpl*/) {
666    return "chain";
667}
668
669static void llama_sampler_chain_accept(struct llama_sampler * smpl, llama_token token) {
670    auto * chain = (llama_sampler_chain *) smpl->ctx;
671
672    time_meas tm(chain->t_sample_us, chain->params.no_perf);
673
674    for (auto & smpl : chain->samplers) {
675        llama_sampler_accept(smpl.ptr, token);
676    }
677
678    chain->n_sample++;
679}
680
681static void llama_sampler_chain_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
682    auto * chain = (llama_sampler_chain *) smpl->ctx;
683
684    time_meas tm(chain->t_sample_us, chain->params.no_perf);
685
686    bool is_backend = chain->is_init;
687
688    for (auto & smpl : chain->samplers) {
689        if (is_backend && smpl.is_backend) {
690            continue;
691        }
692
693        is_backend = false;
694
695        if (smpl.ptr->iface->apply == nullptr) {
696            continue;
697        }
698
699        llama_sampler_apply(smpl.ptr, cur_p);
700    }
701}
702
703static void llama_sampler_chain_reset(struct llama_sampler * smpl) {
704    auto * chain = (llama_sampler_chain *) smpl->ctx;
705
706    for (auto & smpl : chain->samplers) {
707        llama_sampler_reset(smpl.ptr);
708    }
709}
710
711static struct llama_sampler * llama_sampler_chain_clone(const struct llama_sampler * smpl) {
712    const auto * chain_src = (const llama_sampler_chain *) smpl->ctx;
713
714    auto * result = llama_sampler_chain_init(chain_src->params);
715
716    for (const auto & smpl : chain_src->samplers) {
717        llama_sampler_chain_add(result, llama_sampler_clone(smpl.ptr));
718    }
719
720    return result;
721}
722
723static void llama_sampler_chain_free(struct llama_sampler * smpl) {
724    auto * chain = (llama_sampler_chain *) smpl->ctx;
725
726    for (auto & smpl : chain->samplers) {
727        llama_sampler_free(smpl.ptr);
728    }
729
730    delete chain;
731}
732
733static bool llama_sampler_chain_backend_init(
734        struct llama_sampler       * smpl,
735        ggml_backend_buffer_type_t   buft,
736        uint32_t                     n_outputs_max_per_seq) {
737    auto * chain = (llama_sampler_chain *) smpl->ctx;
738
739    GGML_ASSERT(chain->is_init == false && "llama_sampler_chain_backend_init() called twice");
740
741    chain->is_init = true;
742
743    bool res = true;
744    bool backend_prefix = true;
745
746    for (auto & smpl : chain->samplers) {
747        bool cur_prefix = backend_prefix;
748
749        // to be able to run a sampler on the backend, it has to:
750        // - have the .backend_init() API implemented
751        // - return true during .backend_init()
752        // - support the requested per-sequence output limit
753        if (cur_prefix && smpl.ptr->iface->backend_init) {
754            if (!smpl.ptr->iface->backend_init(smpl.ptr, buft, n_outputs_max_per_seq)) {
755                cur_prefix = false;
756            }
757        } else {
758            cur_prefix = false;
759        }
760
761        smpl.is_backend = cur_prefix;
762        backend_prefix = cur_prefix;
763
764        res = res && cur_prefix;
765    }
766
767    auto probe = llama_sampler_backend_probe_graph(smpl, 1024*1024, GGML_DEFAULT_GRAPH_SIZE, false);
768    chain->n_nodes = llama_sampler_backend_probe_n_nodes(probe);
769
770    return res;
771}
772
773static void llama_sampler_chain_backend_accept(
774        struct llama_sampler * smpl,
775        ggml_context * ctx,
776        ggml_cgraph * gf,
777        struct ggml_tensor * selected_token) {
778    auto * chain = (llama_sampler_chain *) smpl->ctx;
779
780    for (auto & smpl : chain->samplers) {
781        if (!smpl.is_backend) {
782            break;
783        }
784
785        if (smpl.ptr->iface->backend_accept) {
786            smpl.ptr->iface->backend_accept(smpl.ptr, ctx, gf, selected_token);
787        }
788    }
789}
790
791static void llama_sampler_chain_backend_apply(
792          struct llama_sampler      * smpl,
793          struct ggml_context       * ctx,
794          struct ggml_cgraph        * gf,
795          struct llama_sampler_data * data) {
796    auto * chain = (llama_sampler_chain *) smpl->ctx;
797
798    GGML_ASSERT(chain->is_init && "llama_sampler_chain_backend_init() not called");
799
800    for (auto & smpl : chain->samplers) {
801        if (!smpl.is_backend) {
802            break;
803        }
804
805        if (smpl.ptr->iface->backend_apply) {
806            smpl.ptr->iface->backend_apply(smpl.ptr, ctx, gf, data);
807        }
808    }
809}
810
811static void llama_sampler_chain_backend_set_input(struct llama_sampler * smpl) {
812    auto * chain = (llama_sampler_chain *) smpl->ctx;
813
814    for (auto & smpl : chain->samplers) {
815        if (!smpl.is_backend) {
816            break;
817        }
818
819        if (smpl.ptr->iface->backend_set_input) {
820            smpl.ptr->iface->backend_set_input(smpl.ptr);
821        }
822    }
823}
824
825static void llama_sampler_chain_backend_reset(struct llama_sampler * smpl) {
826    auto * chain = (llama_sampler_chain *) smpl->ctx;
827
828    for (auto & entry : chain->samplers) {
829        if (!entry.is_backend) {
830            break;
831        }
832        if (entry.ptr->iface->backend_reset) {
833            entry.ptr->iface->backend_reset(entry.ptr);
834        }
835    }
836}
837
838static void llama_sampler_chain_copy_state(const struct llama_sampler * src, struct llama_sampler * dst) {
839    const auto * src_chain = (const llama_sampler_chain *) src->ctx;
840    auto * dst_chain = (llama_sampler_chain *) dst->ctx;
841
842    GGML_ASSERT(src_chain->samplers.size() == dst_chain->samplers.size());
843
844    for (size_t i = 0; i < src_chain->samplers.size(); ++i) {
845        llama_sampler_copy(src_chain->samplers[i].ptr, dst_chain->samplers[i].ptr);
846    }
847
848    // note: is_init, n_nodes and is_backend belong to the current sampling graph
849    dst_chain->params      = src_chain->params;
850    dst_chain->cur         = src_chain->cur;
851    dst_chain->t_sample_us = src_chain->t_sample_us;
852    dst_chain->n_sample    = src_chain->n_sample;
853}
854
855static struct llama_sampler_i llama_sampler_chain_i = {
856    /* .name              = */ llama_sampler_chain_name,
857    /* .accept            = */ llama_sampler_chain_accept,
858    /* .apply             = */ llama_sampler_chain_apply,
859    /* .reset             = */ llama_sampler_chain_reset,
860    /* .clone             = */ llama_sampler_chain_clone,
861    /* .free              = */ llama_sampler_chain_free,
862    /* .backend_init      = */ llama_sampler_chain_backend_init,
863    /* .backend_accept    = */ llama_sampler_chain_backend_accept,
864    /* .backend_apply     = */ llama_sampler_chain_backend_apply,
865    /* .backend_set_input = */ llama_sampler_chain_backend_set_input,
866    /* .backend_reset     = */ llama_sampler_chain_backend_reset,
867    /* .copy_state        = */ llama_sampler_chain_copy_state,
868};
869
870struct llama_sampler * llama_sampler_chain_init(struct llama_sampler_chain_params params) {
871    return llama_sampler_init(
872        /* .iface = */ &llama_sampler_chain_i,
873        /* .ctx   = */ new llama_sampler_chain {
874            /* .params               = */ params,
875            /* .is_init              = */ false,
876            /* .n_nodes              = */ 0,
877            /* .samplers             = */ {},
878            /* .cur                  = */ {},
879            /* .t_sample_us          = */ 0,
880            /* .n_sample             = */ 0,
881        }
882    );
883}
884
885uint32_t llama_sampler_backend_n_nodes(const llama_sampler * sampler) {
886    GGML_ASSERT(sampler != nullptr);
887    GGML_ASSERT(sampler->iface == &llama_sampler_chain_i);
888
889    const auto * chain = (const llama_sampler_chain *) sampler->ctx;
890    GGML_ASSERT(chain->is_init);
891
892    return chain->n_nodes;
893}
894
895llama_token llama_sampler_sample(struct llama_sampler * smpl, struct llama_context * ctx, int32_t idx) {
896    const llama_token   sampled_token  = llama_get_sampled_token_ith     (ctx, idx);
897    const float *       sampled_probs  = llama_get_sampled_probs_ith     (ctx, idx);
898    const float *       sampled_logits = llama_get_sampled_logits_ith    (ctx, idx);
899    const llama_token * sampled_ids    = llama_get_sampled_candidates_ith(ctx, idx);
900
901    // If a backend sampler has already sampled a token, return it.
902    if (sampled_token != LLAMA_TOKEN_NULL) {
903        LLAMA_LOG_DEBUG("%s: Backend sampler selected token for idx %d. Skipping CPU samplers\n", __func__, idx);
904        llama_sampler_accept(smpl, sampled_token);
905        return sampled_token;
906    }
907
908    const llama_model * model = llama_get_model(ctx);
909    const llama_vocab * vocab = llama_model_get_vocab(model);
910
911    const int n_vocab = llama_vocab_n_tokens(vocab);
912
913    // use pre-allocated buffer from chain if available, otherwise allocate locally
914    std::vector<llama_token_data> * cur_ptr;
915    std::vector<llama_token_data> cur_local;
916
917    if (smpl->iface == &llama_sampler_chain_i) {
918        auto * chain = (llama_sampler_chain *) smpl->ctx;
919        cur_ptr = &chain->cur;
920    } else {
921        cur_ptr = &cur_local;
922    }
923
924    auto & cur = *cur_ptr;
925
926    if (sampled_probs) {
927        const uint32_t sampled_probs_count = llama_get_sampled_probs_count_ith(ctx, idx);
928        cur.resize(sampled_probs_count);
929        for (uint32_t i = 0; i < sampled_probs_count; ++i) {
930            cur[i] = llama_token_data{sampled_ids[i], sampled_logits[i], sampled_probs[i]};
931        }
932    } else if (sampled_logits) {
933        const uint32_t sampled_logits_count = llama_get_sampled_logits_count_ith(ctx, idx);
934        cur.resize(sampled_logits_count);
935        for (llama_token i = 0; i < (int)sampled_logits_count; i++) {
936            cur[i] = llama_token_data{sampled_ids[i], sampled_logits[i], 0.0f};
937        }
938    } else {
939        const auto * logits = llama_get_logits_ith(ctx, idx);
940        GGML_ASSERT(logits != nullptr);
941        cur.resize(n_vocab);
942        for (llama_token token_id = 0; token_id < n_vocab; token_id++) {
943            cur[token_id] = llama_token_data{token_id, logits[token_id], 0.0f};
944        }
945    }
946
947    llama_token_data_array cur_p = {
948        /* .data       = */ cur.data(),
949        /* .size       = */ cur.size(),
950        /* .selected   = */ -1,
951        /* .sorted     = */ false,
952    };
953
954    llama_sampler_apply(smpl, &cur_p);
955
956    GGML_ASSERT(cur_p.selected >= 0 && cur_p.selected < (int32_t) cur_p.size);
957
958    auto token = cur_p.data[cur_p.selected].id;
959
960    llama_sampler_accept(smpl, token);
961
962    return token;
963}
964
965
966void llama_sampler_chain_add(struct llama_sampler * chain, struct llama_sampler * smpl) {
967    auto * p = (llama_sampler_chain *) chain->ctx;
968    p->samplers.push_back({
969        /* .is_backend = */ false,
970        /* .ptr        = */ smpl,
971    });
972}
973
974struct llama_sampler * llama_sampler_chain_get(struct llama_sampler * chain, int32_t i) {
975    if (chain == nullptr) {
976        return nullptr;
977    }
978
979    if (chain->iface != &llama_sampler_chain_i) {
980        return nullptr;
981    }
982
983    if (i == -1) {
984        return chain;
985    }
986
987    const auto * p = (const llama_sampler_chain *) chain->ctx;
988
989    if (i < 0 || (size_t) i >= p->samplers.size()) {
990        return nullptr;
991    }
992
993    return p->samplers[i].ptr;
994}
995
996struct llama_sampler * llama_sampler_chain_remove(struct llama_sampler * chain, int32_t i) {
997    auto * p = (llama_sampler_chain *) chain->ctx;
998
999    if (i < 0 || (size_t) i >= p->samplers.size()) {
1000        return nullptr;
1001    }
1002
1003    auto * result = p->samplers[i].ptr;
1004    p->samplers.erase(p->samplers.begin() + i);
1005
1006    return result;
1007}
1008
1009int32_t llama_sampler_chain_n(const struct llama_sampler * chain) {
1010    const auto * p = (const llama_sampler_chain *) chain->ctx;
1011
1012    return p->samplers.size();
1013}
1014
1015//
1016// samplers
1017//
1018
1019// greedy
1020
1021struct llama_sampler_greedy : public llama_sampler_backend {
1022};
1023
1024static const char * llama_sampler_greedy_name(const struct llama_sampler * smpl) {
1025    auto * sctx = (llama_sampler_greedy *) smpl->ctx;
1026    return sctx->get_name();
1027}
1028
1029static void llama_sampler_greedy_reset(struct llama_sampler * smpl) {
1030    auto * ctx = (llama_sampler_greedy *) smpl->ctx;
1031    GGML_UNUSED(ctx);
1032}
1033
1034static struct llama_sampler * llama_sampler_greedy_clone(const struct llama_sampler * smpl) {
1035    const auto * ctx = (const llama_sampler_greedy *) smpl->ctx;
1036    auto * result = llama_sampler_init_greedy();
1037
1038    // copy the state
1039    {
1040        auto * result_ctx = (llama_sampler_greedy *) result->ctx;
1041
1042        GGML_UNUSED(ctx);
1043        GGML_UNUSED(result_ctx);
1044    }
1045
1046    return result;
1047}
1048
1049static void llama_sampler_greedy_free(struct llama_sampler * smpl) {
1050    delete (llama_sampler_greedy *) smpl->ctx;
1051}
1052
1053static void llama_sampler_greedy_apply(struct llama_sampler * /*smpl*/, llama_token_data_array * cur_p) {
1054    cur_p->selected = 0;
1055    for (size_t i = 1; i < cur_p->size; ++i) {
1056        if (cur_p->data[i].logit > cur_p->data[cur_p->selected].logit) {
1057            cur_p->selected = i;
1058        }
1059    }
1060}
1061
1062static bool llama_sampler_greedy_backend_init(
1063        struct llama_sampler       * smpl,
1064        ggml_backend_buffer_type_t   buft,
1065        uint32_t                     n_outputs_max_per_seq) {
1066    auto * sctx = (llama_sampler_greedy *) smpl->ctx;
1067    GGML_UNUSED(n_outputs_max_per_seq);
1068
1069    const bool res = llama_sampler_backend_support(smpl, buft);
1070
1071    sctx->init(res);
1072
1073    return res;
1074}
1075
1076static void llama_sampler_greedy_backend_apply(
1077        struct llama_sampler      * smpl,
1078        struct ggml_context       * ctx,
1079        struct ggml_cgraph        * gf,
1080        struct llama_sampler_data * data) {
1081    GGML_UNUSED(gf);
1082    GGML_UNUSED(smpl);
1083
1084    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
1085
1086    struct ggml_tensor * curl = ggml_argmax(ctx, logits);
1087    ggml_set_name(curl, "greedy_argmax");
1088
1089    data->sampled = curl;
1090}
1091
1092static struct llama_sampler_i llama_sampler_greedy_i = {
1093    /* .name              = */ llama_sampler_greedy_name,
1094    /* .accept            = */ nullptr,
1095    /* .apply             = */ llama_sampler_greedy_apply,
1096    /* .reset             = */ llama_sampler_greedy_reset,
1097    /* .clone             = */ llama_sampler_greedy_clone,
1098    /* .free              = */ llama_sampler_greedy_free,
1099    /* .backend_init      = */ llama_sampler_greedy_backend_init,
1100    /* .backend_accept    = */ nullptr,
1101    /* .backend_apply     = */ llama_sampler_greedy_backend_apply,
1102    /* .backend_set_input = */ nullptr,
1103    /* .backend_reset     = */ nullptr,
1104    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_greedy>,
1105};
1106
1107struct llama_sampler * llama_sampler_init_greedy() {
1108    return llama_sampler_init(
1109        /* .iface = */ &llama_sampler_greedy_i,
1110        /* .ctx   = */ new llama_sampler_greedy {
1111            ("greedy"),
1112        }
1113    );
1114}
1115
1116// dist
1117
1118struct llama_sampler_dist : public llama_sampler_backend {
1119    const uint32_t seed;
1120          uint32_t seed_cur;
1121
1122    std::mt19937 rng;
1123
1124    // TODO: refactor + fix naming
1125    //       https://github.com/ggml-org/llama.cpp/pull/25532/changes#r3749906719
1126    // use a temporary RNG for multi-output sampling so rejected tokens do not advance rng
1127    bool backend_transactional;
1128    std::mt19937 rng_backend;
1129    size_t n_backend_draws_generated;
1130    size_t n_backend_draws_committed;
1131
1132    // inputs for the current sampling graph
1133    std::vector<ggml_tensor *> inp_uniforms;
1134
1135    void copy_state(const llama_sampler_dist & src) {
1136        // note: inp_uniforms and backend_transactional belong to the current sampling graph
1137        seed_cur                  = src.seed_cur;
1138        rng                       = src.rng;
1139        rng_backend               = src.rng_backend;
1140        n_backend_draws_generated = src.n_backend_draws_generated;
1141        n_backend_draws_committed = src.n_backend_draws_committed;
1142    }
1143};
1144
1145static const char * llama_sampler_dist_name(const struct llama_sampler * smpl) {
1146    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1147    return sctx->get_name();
1148}
1149
1150static void llama_sampler_dist_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
1151    auto * ctx = (llama_sampler_dist *) smpl->ctx;
1152
1153    // edge cases
1154    if (cur_p->size == 0) {
1155        cur_p->selected = -1;
1156        return;
1157    }
1158
1159    cur_p->selected = 0;
1160
1161    std::uniform_real_distribution<double> dist(0.0f, 1.0f);
1162
1163    if (cur_p->size == 1) {
1164        // keep the RNG state aligned with backend sampling, which draws once per output
1165        dist(ctx->rng);
1166        cur_p->data[0].p = 1.0f;
1167        return;
1168    }
1169
1170    // max logit for numerical stability
1171    float max_l = cur_p->data[0].logit;
1172    if (!cur_p->sorted) {
1173        for (size_t i = 1; i < cur_p->size; ++i) {
1174            max_l = std::max(max_l, cur_p->data[i].logit);
1175        }
1176    }
1177
1178    // apply softmax to obtain the probabilities
1179    double sum_cum = 0.0f;
1180    for (size_t i = 0; i < cur_p->size; ++i) {
1181        float p = expf(cur_p->data[i].logit - max_l);
1182        cur_p->data[i].p = p;
1183        sum_cum += p;
1184    }
1185
1186#if 1
1187    // sample from the obtained probabilities and normalize the probs in a single pass
1188    // this is ~3x faster on Mac with full gpt-oss vocab than the version below
1189    //
1190    const double rnd = dist(ctx->rng);
1191
1192          double sum_run = 0.0f;
1193    const double sum_tgt = sum_cum*rnd;
1194
1195    bool found = false;
1196    for (size_t i = 0; i < cur_p->size; ++i) {
1197        if (!found) {
1198            // accumulate probs until we reach the target sum
1199            sum_run += cur_p->data[i].p;
1200            if (sum_run >= sum_tgt) {
1201                cur_p->selected = i;
1202                found = true;
1203            }
1204        }
1205
1206        // normalize probs
1207        cur_p->data[i].p /= sum_cum;
1208    }
1209
1210    // fallback to the last token (don't think this can happen)
1211    assert(found);
1212    if (!found) {
1213        cur_p->selected = cur_p->size - 1;
1214    }
1215#else
1216    // for clarity, this is the same as above but does one pass for normalization and one extra pass for sampling
1217    for (size_t i = 0; i < cur_p->size; ++i) {
1218        cur_p->data[i].p /= sum_cum;
1219    }
1220
1221    cur_p->selected = llama_sample_dist(cur_p, ctx->rng);
1222#endif
1223}
1224
1225static void llama_sampler_dist_reset(struct llama_sampler * smpl) {
1226    auto * ctx = (llama_sampler_dist *) smpl->ctx;
1227    ctx->seed_cur = get_rng_seed(ctx->seed);
1228    ctx->rng.seed(ctx->seed_cur);
1229    ctx->rng_backend = ctx->rng;
1230    ctx->n_backend_draws_generated = 0;
1231    ctx->n_backend_draws_committed = 0;
1232}
1233
1234static struct llama_sampler * llama_sampler_dist_clone(const struct llama_sampler * smpl) {
1235    const auto * ctx = (const llama_sampler_dist *) smpl->ctx;
1236    auto * result = llama_sampler_init_dist(ctx->seed);
1237
1238    // copy the state
1239    {
1240        auto * result_ctx = (llama_sampler_dist *) result->ctx;
1241
1242        result_ctx->seed_cur                  = ctx->seed_cur;
1243        result_ctx->rng                       = ctx->rng;
1244        result_ctx->backend_transactional     = ctx->backend_transactional;
1245        result_ctx->rng_backend               = ctx->rng_backend;
1246        result_ctx->n_backend_draws_generated = ctx->n_backend_draws_generated;
1247        result_ctx->n_backend_draws_committed = ctx->n_backend_draws_committed;
1248    }
1249
1250    return result;
1251}
1252
1253static void llama_sampler_dist_free(struct llama_sampler * smpl) {
1254    delete (llama_sampler_dist *) smpl->ctx;
1255}
1256
1257static bool llama_sampler_dist_backend_init(
1258        struct llama_sampler       * smpl,
1259        ggml_backend_buffer_type_t   buft,
1260        uint32_t                     n_outputs_max_per_seq) {
1261    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1262
1263    const bool res = llama_sampler_backend_support(smpl, buft);
1264
1265    sctx->init(res);
1266    sctx->backend_transactional = n_outputs_max_per_seq > 1;
1267    sctx->rng_backend = sctx->rng;
1268    sctx->n_backend_draws_generated = 0;
1269    sctx->n_backend_draws_committed = 0;
1270
1271    return res;
1272}
1273
1274static void llama_sampler_dist_backend_apply(
1275        struct llama_sampler      * smpl,
1276        struct ggml_context       * ctx,
1277        struct ggml_cgraph        * gf,
1278        struct llama_sampler_data * data) {
1279    GGML_UNUSED(gf);
1280
1281    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1282
1283    ggml_tensor * inp_uniform = ggml_new_tensor_1d(ctx, GGML_TYPE_F32, 1);
1284    ggml_format_name(inp_uniform, "uniform_%zu", sctx->inp_uniforms.size());
1285    ggml_set_input(inp_uniform);
1286    sctx->inp_uniforms.push_back(inp_uniform);
1287
1288    // flatten
1289    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
1290
1291    struct ggml_tensor * probs = ggml_soft_max(ctx, logits);
1292    ggml_set_name(probs, "dist_probs");
1293
1294    struct ggml_tensor * cumsum = ggml_cumsum(ctx, probs);
1295    ggml_set_name(cumsum, "dist_cumsum");
1296
1297    // The uniform tensor has a random value and we subtract this tensor with
1298    // the cumsum tensor (the uniform tensor will be broadcasted by ggml_sub).
1299    // Recall that each entry in cumsum is the cumulative probability up to that
1300    // index so values stay negative while the cumulative total is below the
1301    // random value, and become zero/positive once the threshold is crossed.
1302    struct ggml_tensor * diff = ggml_sub(ctx, cumsum, inp_uniform);
1303    ggml_set_name(diff, "dist_cumsum");
1304
1305    // The ggml_step function produces a tensor where entries are 1 if the
1306    // corresponding entry in diff is > 0, and 0 otherwise. So all values up to
1307    // the index where the cumulative probability exceeds the random value are 0,
1308    // and all entries after that are 1.
1309    struct ggml_tensor * mask = ggml_step(ctx, diff);
1310    ggml_set_name(mask, "dist_mask");
1311
1312    // Taking the sum of the mask gives us the sum of elements after the threshold
1313    // we are interested in.
1314    struct ggml_tensor * idxf = ggml_sum(ctx, mask);
1315    ggml_set_name(idxf, "dist_index_f32");
1316
1317    // Clamp to prevent out-of-bounds access when computing the index.
1318    idxf = ggml_clamp(ctx, idxf, 1.0f, mask->ne[0]);
1319
1320    // Use ggml_scale_bias to scale the index value by -1 and then add the size
1321    // of the mask to that value so we get the correct index ((-1 * idxf) + n).
1322    struct ggml_tensor * idx = ggml_cast(ctx, ggml_scale_bias(ctx, idxf, -1.0f, mask->ne[0]), GGML_TYPE_I32);
1323    ggml_set_name(idx, "dist_index_i32");
1324
1325    // Map back to original vocab ids if a candidates tensor is available.
1326    struct ggml_tensor * sampled_token = idx;
1327    if (data->candidates != nullptr) {
1328        struct ggml_tensor * candidates = ggml_reshape_2d(ctx, data->candidates, 1, ggml_nelements(data->candidates));
1329
1330        sampled_token = ggml_get_rows(ctx, candidates, idx);
1331        ggml_set_name(sampled_token, "dist_sampled_token");
1332    }
1333
1334    data->sampled = sampled_token;
1335    data->probs = probs;
1336}
1337
1338static void llama_sampler_dist_backend_set_input(struct llama_sampler * smpl) {
1339    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1340
1341    GGML_ASSERT(!sctx->inp_uniforms.empty());
1342
1343    // We sample in double precision and cast to float to match rnd numbers of
1344    // llama_sampler_dist which uses double precision (sampling from
1345    // std::uniform_real_distribution<double> and
1346    // std::uniform_real_distribution<float> with same rng will produce
1347    // different sequences).
1348    std::uniform_real_distribution<double> dist(0.0f, 1.0f);
1349
1350    auto & rng = sctx->backend_transactional ? sctx->rng_backend : sctx->rng;
1351
1352    for (auto * inp_uniform : sctx->inp_uniforms) {
1353        GGML_ASSERT(inp_uniform != nullptr);
1354
1355        const float rnd = dist(rng);
1356        ggml_backend_tensor_set(inp_uniform, &rnd, 0, sizeof(float));
1357
1358        if (sctx->backend_transactional) {
1359            ++sctx->n_backend_draws_generated;
1360        }
1361    }
1362}
1363
1364static void llama_sampler_dist_backend_reset(struct llama_sampler * smpl) {
1365    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1366    sctx->inp_uniforms.clear();
1367}
1368
1369static void llama_sampler_dist_accept(struct llama_sampler * smpl, llama_token token) {
1370    GGML_UNUSED(token);
1371
1372    auto * sctx = (llama_sampler_dist *) smpl->ctx;
1373
1374    if (!sctx->backend_transactional ||
1375            sctx->n_backend_draws_committed >= sctx->n_backend_draws_generated) {
1376        return;
1377    }
1378
1379    std::uniform_real_distribution<double> dist(0.0f, 1.0f);
1380    dist(sctx->rng);
1381    ++sctx->n_backend_draws_committed;
1382}
1383
1384static struct llama_sampler_i llama_sampler_dist_i = {
1385    /* .name              = */ llama_sampler_dist_name,
1386    /* .accept            = */ llama_sampler_dist_accept,
1387    /* .apply             = */ llama_sampler_dist_apply,
1388    /* .reset             = */ llama_sampler_dist_reset,
1389    /* .clone             = */ llama_sampler_dist_clone,
1390    /* .free              = */ llama_sampler_dist_free,
1391    /* .backend_init      = */ llama_sampler_dist_backend_init,
1392    /* .backend_accept    = */ nullptr,
1393    /* .backend_apply     = */ llama_sampler_dist_backend_apply,
1394    /* .backend_set_input = */ llama_sampler_dist_backend_set_input,
1395    /* .backend_reset     = */ llama_sampler_dist_backend_reset,
1396    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_dist>,
1397};
1398
1399struct llama_sampler * llama_sampler_init_dist(uint32_t seed) {
1400    auto seed_cur = get_rng_seed(seed);
1401    return llama_sampler_init(
1402        /* .iface = */ &llama_sampler_dist_i,
1403        /* .ctx   = */ new llama_sampler_dist {
1404            ("dist"),
1405            /* .seed                      = */ seed,
1406            /* .seed_cur                  = */ seed_cur,
1407            /* .rng                       = */ std::mt19937(seed_cur),
1408            /* .backend_transactional     = */ false,
1409            /* .rng_backend               = */ std::mt19937(seed_cur),
1410            /* .n_backend_draws_generated = */ 0,
1411            /* .n_backend_draws_committed = */ 0,
1412            /* .inp_uniforms              = */ {},
1413        }
1414    );
1415}
1416
1417void llama_sampler_backend_begin(llama_sampler * sampler) {
1418    GGML_ASSERT(sampler != nullptr);
1419
1420    if (sampler->iface == &llama_sampler_chain_i) {
1421        auto * chain = (llama_sampler_chain *) sampler->ctx;
1422        for (auto & entry : chain->samplers) {
1423            if (!entry.is_backend) {
1424                break;
1425            }
1426            llama_sampler_backend_begin(entry.ptr);
1427        }
1428    } else if (sampler->iface == &llama_sampler_dist_i) {
1429        auto * ctx = (llama_sampler_dist *) sampler->ctx;
1430        if (ctx->backend_transactional) {
1431            ctx->rng_backend = ctx->rng;
1432            ctx->n_backend_draws_generated = 0;
1433            ctx->n_backend_draws_committed = 0;
1434        }
1435    }
1436}
1437
1438// top-k
1439
1440struct llama_sampler_top_k : public llama_sampler_backend {
1441    const int32_t k;
1442};
1443
1444static const char * llama_sampler_top_k_name(const struct llama_sampler * smpl) {
1445    auto * sctx = (llama_sampler_top_k *) smpl->ctx;
1446    return sctx->get_name();
1447}
1448
1449static void llama_sampler_top_k_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
1450    auto * ctx = (llama_sampler_top_k *) smpl->ctx;
1451    llama_sampler_top_k_impl(cur_p, ctx->k);
1452}
1453
1454static struct llama_sampler * llama_sampler_top_k_clone(const struct llama_sampler * smpl) {
1455    const auto * ctx = (const llama_sampler_top_k *) smpl->ctx;
1456    return llama_sampler_init_top_k(ctx->k);
1457}
1458
1459static void llama_sampler_top_k_free(struct llama_sampler * smpl) {
1460    delete (llama_sampler_top_k *) smpl->ctx;
1461}
1462
1463static bool llama_sampler_top_k_backend_init(
1464        struct llama_sampler       * smpl,
1465        ggml_backend_buffer_type_t   buft,
1466        uint32_t                     n_outputs_max_per_seq) {
1467    auto * sctx = (llama_sampler_top_k *) smpl->ctx;
1468    GGML_UNUSED(n_outputs_max_per_seq);
1469
1470    const bool res = llama_sampler_backend_support(smpl, buft);
1471
1472    sctx->init(res);
1473
1474    return res;
1475}
1476
1477static void llama_sampler_top_k_backend_apply(
1478        struct llama_sampler      * smpl,
1479        struct ggml_context       * ctx,
1480        struct ggml_cgraph        * gf,
1481        struct llama_sampler_data * data) {
1482    auto * sctx = (llama_sampler_top_k *) smpl->ctx;
1483
1484    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
1485
1486    struct ggml_tensor * top_k = ggml_top_k(ctx, logits, sctx->k);
1487    ggml_set_name(top_k, "top_k");
1488
1489    if (data->candidates) {
1490        struct ggml_tensor * candidates_rows = ggml_reshape_2d(ctx, data->candidates, 1, data->candidates->ne[0]);
1491        data->candidates = ggml_get_rows(ctx, candidates_rows, top_k);
1492        ggml_set_name(data->candidates, "top_k_candidates");
1493    } else {
1494        data->candidates = top_k;
1495    }
1496
1497    struct ggml_tensor * logits_rows = ggml_reshape_2d(ctx, logits, 1, logits->ne[0]);
1498    data->logits = ggml_get_rows(ctx, logits_rows, top_k);
1499    ggml_set_name(data->logits, "top_k_rows");
1500
1501    GGML_UNUSED(gf);
1502}
1503
1504static struct llama_sampler_i llama_sampler_top_k_i = {
1505    /* .name              = */ llama_sampler_top_k_name,
1506    /* .accept            = */ nullptr,
1507    /* .apply             = */ llama_sampler_top_k_apply,
1508    /* .reset             = */ nullptr,
1509    /* .clone             = */ llama_sampler_top_k_clone,
1510    /* .free              = */ llama_sampler_top_k_free,
1511    /* .backend_init      = */ llama_sampler_top_k_backend_init,
1512    /* .backend_accept    = */ nullptr,
1513    /* .backend_apply     = */ llama_sampler_top_k_backend_apply,
1514    /* .backend_set_input = */ nullptr,
1515    /* .backend_reset     = */ nullptr,
1516    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_top_k>,
1517};
1518
1519struct llama_sampler * llama_sampler_init_top_k(int32_t k) {
1520    const bool is_empty = (k <= 0);
1521
1522    if (is_empty) {
1523        return llama_sampler_init_empty("?top-k");
1524    }
1525
1526    return llama_sampler_init(
1527        /* .iface = */ &llama_sampler_top_k_i,
1528        /* .ctx   = */ new llama_sampler_top_k {
1529            ("top-k"),
1530            /* .k = */ k,
1531        }
1532    );
1533}
1534
1535// top-p
1536
1537struct llama_sampler_top_p : public llama_sampler_backend {
1538    const float  p;
1539    const size_t min_keep;
1540
1541    std::vector<llama_token_data> buf_sort;
1542};
1543
1544static const char * llama_sampler_top_p_name(const struct llama_sampler * smpl) {
1545    auto * sctx = (llama_sampler_top_p *) smpl->ctx;
1546    return sctx->get_name();
1547}
1548
1549static void llama_sampler_top_p_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
1550    auto * ctx = (llama_sampler_top_p *) smpl->ctx;
1551
1552    if (ctx->p >= 1.0f) {
1553        return;
1554    }
1555
1556    llama_sampler_softmax_impl(cur_p, false);
1557
1558    size_t k = cur_p->size;
1559    auto * pdata = cur_p->data;
1560
1561    auto & buf_sort = ctx->buf_sort;
1562
1563    // if not sorted, try adaptive top-k sorting
1564    if (!cur_p->sorted && cur_p->size > 1024) {
1565        k = std::min<size_t>(256, cur_p->size);
1566        llama_token_data_array_partial_sort(*cur_p, k, buf_sort);
1567        pdata = buf_sort.data();
1568    } else if (!cur_p->sorted) {
1569        // small candidates -> sort inplace
1570        llama_token_data_array_partial_sort_inplace(cur_p, k);
1571    }
1572
1573    // Compute the cumulative probabilities
1574    float cum_sum = 0.0f;
1575    size_t last_idx = cur_p->size;
1576
1577    for (size_t i = 0; i < cur_p->size; ++i) {
1578        cum_sum += pdata[i].p;
1579
1580        // Check if the running sum is at least p or if we have kept at least min_keep tokens
1581        // we set the last index to i+1 to indicate that the current iterate should be included in the set
1582        if (cum_sum >= ctx->p && i + 1 >= ctx->min_keep) {
1583            last_idx = i + 1;
1584            break;
1585        }
1586
1587        // we exceeded the current top-k heuristic -> increase k and continue
1588        if (!cur_p->sorted && i == k - 1) {
1589            k = cur_p->size;
1590            llama_token_data_array_partial_sort(*cur_p, k, buf_sort);
1591            pdata = buf_sort.data();
1592        }
1593    }
1594
1595    // Resize the output vector to keep only the top-p tokens
1596    if (!cur_p->sorted) {
1597        std::copy(buf_sort.data(), buf_sort.data() + last_idx, cur_p->data);
1598        cur_p->sorted = true;
1599    }
1600
1601    cur_p->size = last_idx;
1602}
1603
1604static struct llama_sampler * llama_sampler_top_p_clone(const struct llama_sampler * smpl) {
1605    const auto * ctx = (const llama_sampler_top_p *) smpl->ctx;
1606    return llama_sampler_init_top_p(ctx->p, ctx->min_keep);
1607}
1608
1609static void llama_sampler_top_p_free(struct llama_sampler * smpl) {
1610    delete (llama_sampler_top_p *) smpl->ctx;
1611}
1612
1613static bool llama_sampler_top_p_backend_init(
1614        struct llama_sampler       * smpl,
1615        ggml_backend_buffer_type_t   buft,
1616        uint32_t                     n_outputs_max_per_seq) {
1617    auto * sctx = (llama_sampler_top_p *) smpl->ctx;
1618    GGML_UNUSED(n_outputs_max_per_seq);
1619
1620    const bool res = llama_sampler_backend_support(smpl, buft);
1621
1622    sctx->init(res);
1623
1624    return res;
1625}
1626
1627static void llama_sampler_top_p_backend_apply(
1628        struct llama_sampler      * smpl,
1629        struct ggml_context       * ctx,
1630        struct ggml_cgraph        * gf,
1631        struct llama_sampler_data * data) {
1632    auto * sctx = (llama_sampler_top_p *) smpl->ctx;
1633
1634    // flatten
1635    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
1636
1637    auto ggml_sort = [ctx](struct ggml_tensor * a, struct ggml_tensor * b) {
1638        GGML_ASSERT(ggml_nrows(a) == 1);
1639        struct ggml_tensor * a_reshaped = ggml_reshape_2d(ctx, a, 1, a->ne[0]);
1640        struct ggml_tensor * a_sorted   = ggml_get_rows(ctx, a_reshaped, b);
1641        return a_sorted;
1642    };
1643
1644    // Get the sorted logits in descending order.
1645    struct ggml_tensor * sorted_idx = ggml_argsort(ctx, logits, GGML_SORT_ORDER_DESC);
1646    ggml_set_name(sorted_idx, "top_p_sorted_idx");
1647
1648    // Do the sorting via reshape + get_rows
1649    struct ggml_tensor * sorted_logits = ggml_sort(logits, sorted_idx);
1650    ggml_set_name(sorted_logits, "top_p_sorted_logits");
1651
1652    sorted_logits = ggml_reshape_1d(ctx, sorted_logits, ggml_nelements(sorted_logits));
1653    struct ggml_tensor * softmax = ggml_soft_max(ctx, sorted_logits);
1654    ggml_set_name(softmax, "top_p_softmax");
1655
1656    // If candidates are provided, sort them as well. Otherwise, set sorted indices as candidates.
1657    if (data->candidates) {
1658        data->candidates = ggml_sort(data->candidates, sorted_idx);
1659    } else {
1660        data->candidates = sorted_idx;
1661    }
1662    ggml_set_name(data->candidates, "top_p_candidates");
1663
1664    // Compute Cumulative Distribution Function (CDF) by means of GGML_OP_CUMSUM.
1665    struct ggml_tensor * cdf = ggml_cumsum(ctx, softmax);
1666    ggml_set_name(cdf, "top_p_cdf");
1667
1668    // Invert CDF and add top-p value so that ggml_step yields 1 for values we want to keep
1669    struct ggml_tensor * cdf_scaled = ggml_scale_bias(ctx, cdf, -1.0f, sctx->p);
1670    ggml_set_name(cdf_scaled, "top_p_cdf_scaled");
1671
1672    struct ggml_tensor * mask = ggml_step(ctx, cdf_scaled);
1673    ggml_set_name(mask, "top_p_mask");
1674
1675    // Taking the sum of the mask gives us the sum of elements after the threshold
1676    // we are interested in.
1677    struct ggml_tensor * idxf = ggml_sum(ctx, mask);
1678    ggml_set_name(idxf, "top_p_index_f32");
1679
1680    // prevent out-of-bounds access
1681    idxf = ggml_clamp(ctx, idxf, 0.0f, mask->ne[0] - 1);
1682
1683    // construct ones tensor to set the value in the mask
1684    struct ggml_tensor * ones = ggml_scale_bias(ctx, idxf, 0.0f, 1.0f);
1685    ggml_set_name(ones, "top_p_ones");
1686
1687    // Make top-p inclusive (i.e. return all values such that cum_sum/cdf >= p)
1688    struct ggml_tensor * mask_reshaped = ggml_reshape_2d(ctx, mask, 1, mask->ne[0]);
1689
1690    mask_reshaped = ggml_set_rows(ctx, mask_reshaped, ones, ggml_cast(ctx, idxf, GGML_TYPE_I32));
1691    mask = ggml_reshape_1d(ctx, mask_reshaped, mask->ne[0]);
1692
1693    // Apply -INFINITY bias for masked-out tokens
1694    // log(1) = 0 (keep), log(0) = -INF (discard)
1695    struct ggml_tensor * top_p_bias = ggml_log(ctx, mask);
1696    ggml_set_name(top_p_bias, "top_p_bias");
1697
1698    data->logits = ggml_add(ctx, sorted_logits, top_p_bias);
1699    ggml_set_name(data->logits, "top_p_logits");
1700
1701    GGML_UNUSED(gf);
1702}
1703
1704static struct llama_sampler_i llama_sampler_top_p_i = {
1705    /* .name              = */ llama_sampler_top_p_name,
1706    /* .accept            = */ nullptr,
1707    /* .apply             = */ llama_sampler_top_p_apply,
1708    /* .reset             = */ nullptr,
1709    /* .clone             = */ llama_sampler_top_p_clone,
1710    /* .free              = */ llama_sampler_top_p_free,
1711    /* .backend_init      = */ llama_sampler_top_p_backend_init,
1712    /* .backend_accept    = */ nullptr,
1713    /* .backend_apply     = */ llama_sampler_top_p_backend_apply,
1714    /* .backend_set_input = */ nullptr,
1715    /* .backend_reset     = */ nullptr,
1716    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_top_p>,
1717};
1718
1719struct llama_sampler * llama_sampler_init_top_p(float p, size_t min_keep) {
1720    const bool is_empty = p >= 1.0f;
1721
1722    if (is_empty) {
1723        return llama_sampler_init_empty("?top-p");
1724    }
1725
1726    return llama_sampler_init(
1727        /* .iface = */ &llama_sampler_top_p_i,
1728        /* .ctx   = */ new llama_sampler_top_p {
1729            ("top-p"),
1730            /* .p        = */ p,
1731            /* .min_keep = */ min_keep,
1732            /* .buf_sort = */ {},
1733        }
1734    );
1735}
1736
1737// min-p
1738
1739struct llama_sampler_min_p : public llama_sampler_backend {
1740    const float  p;
1741    const size_t min_keep;
1742};
1743
1744static const char * llama_sampler_min_p_name(const struct llama_sampler * smpl) {
1745    auto * sctx = (llama_sampler_min_p *) smpl->ctx;
1746    return sctx->get_name();
1747}
1748
1749static void llama_sampler_min_p_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
1750    auto * ctx = (llama_sampler_min_p *) smpl->ctx;
1751
1752    if (ctx->p <= 0.0f || !cur_p->size) {
1753        return;
1754    }
1755
1756    bool min_p_applied = false;
1757
1758    // if the cur_p aren't sorted, try the unsorted implementation first
1759    if (!cur_p->sorted) {
1760        std::vector<llama_token_data> filtered_tokens;
1761
1762        float max_logit = -FLT_MAX;
1763        for (size_t i = 0; i < cur_p->size; ++i) {
1764            max_logit = std::max(max_logit, cur_p->data[i].logit);
1765        }
1766        const float min_logit = max_logit + logf(ctx->p); // min logit for p_i >= p * p_max
1767
1768        for (size_t i = 0; i < cur_p->size; ++i) {
1769            if (cur_p->data[i].logit >= min_logit) {
1770                filtered_tokens.push_back(cur_p->data[i]);
1771            }
1772        }
1773
1774        // if we have enough values the operation was a success
1775        if (!filtered_tokens.empty() && filtered_tokens.size() >= ctx->min_keep) {
1776            std::copy(filtered_tokens.begin(), filtered_tokens.end(), cur_p->data);
1777            cur_p->size = filtered_tokens.size();
1778            min_p_applied = true;
1779        }
1780    }
1781
1782    // if the cur_p are sorted or the unsorted implementation failed, use this implementation
1783    if (!min_p_applied) {
1784        // Sort the logits in descending order
1785        if (!cur_p->sorted) {
1786            llama_token_data_array_partial_sort_inplace(cur_p, cur_p->size);
1787        }
1788
1789        const float min_logit = cur_p->data[0].logit + logf(ctx->p); // min logit for p_i >= p * p_max
1790        size_t i = 1; // first token always matches
1791
1792        for (; i < cur_p->size; ++i) {
1793            if (cur_p->data[i].logit < min_logit && i >= ctx->min_keep) {
1794                break; // prob too small
1795            }
1796        }
1797
1798        // Resize the output vector to keep only the matching tokens
1799        cur_p->size = i;
1800    }
1801}
1802
1803static struct llama_sampler * llama_sampler_min_p_clone(const struct llama_sampler * smpl) {
1804    const auto * ctx = (const llama_sampler_min_p *) smpl->ctx;
1805    return llama_sampler_init_min_p(ctx->p, ctx->min_keep);
1806}
1807
1808static void llama_sampler_min_p_free(struct llama_sampler * smpl) {
1809    delete (llama_sampler_min_p *) smpl->ctx;
1810}
1811
1812static bool llama_sampler_min_p_backend_init(
1813        struct llama_sampler       * smpl,
1814        ggml_backend_buffer_type_t   buft,
1815        uint32_t                     n_outputs_max_per_seq) {
1816    auto * sctx = (llama_sampler_min_p *) smpl->ctx;
1817    GGML_UNUSED(n_outputs_max_per_seq);
1818
1819    const bool res = llama_sampler_backend_support(smpl, buft);
1820
1821    sctx->init(res);
1822
1823    return res;
1824}
1825
1826static void llama_sampler_min_p_backend_apply(
1827        struct llama_sampler      * smpl,
1828        struct ggml_context       * ctx,
1829        struct ggml_cgraph        * gf,
1830        struct llama_sampler_data * data) {
1831    auto * sctx = (llama_sampler_min_p *) smpl->ctx;
1832
1833    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
1834
1835    struct ggml_tensor * max_idx = ggml_argmax(ctx, logits);
1836    ggml_set_name(max_idx, "max_idx");
1837
1838    struct ggml_tensor * logits_rows = ggml_reshape_2d(ctx, logits, 1, logits->ne[0]);
1839    ggml_set_name(logits_rows, "logits_rows");
1840
1841    struct ggml_tensor * max_logit = ggml_get_rows(ctx, logits_rows, max_idx);
1842    ggml_set_name(max_logit, "max_logit");
1843
1844    // Calculate the threshold value.
1845    struct ggml_tensor * threshold = ggml_scale_bias(ctx, max_logit, 1.0f, logf(sctx->p));
1846    ggml_set_name(threshold, "min_p_threshold");
1847
1848    // Subtract the threshold from logits.
1849    struct ggml_tensor * sub = ggml_sub(ctx, logits, threshold);
1850
1851    // Create a mask where logits below the threshold are 0 (discard),
1852    // and others are 1 (keep).
1853    struct ggml_tensor * mask = ggml_step(ctx, sub);
1854    ggml_set_name(mask, "min_p_mask");
1855
1856    // Apply -INFINITY bias for masked-out tokens
1857    // log(1) = 0 (keep), log(0) = -INF (discard)
1858    struct ggml_tensor * min_p_bias = ggml_log(ctx, mask);
1859    ggml_set_name(min_p_bias, "min_p_bias");
1860
1861    data->logits = ggml_add(ctx, logits, min_p_bias);
1862    ggml_set_name(data->logits, "min_p_logits");
1863
1864    GGML_UNUSED(gf);
1865}
1866
1867static struct llama_sampler_i llama_sampler_min_p_i = {
1868    /* .name              = */ llama_sampler_min_p_name,
1869    /* .accept            = */ nullptr,
1870    /* .apply             = */ llama_sampler_min_p_apply,
1871    /* .reset             = */ nullptr,
1872    /* .clone             = */ llama_sampler_min_p_clone,
1873    /* .free              = */ llama_sampler_min_p_free,
1874    /* .backend_init      = */ llama_sampler_min_p_backend_init,
1875    /* .backend_accept    = */ nullptr,
1876    /* .backend_apply     = */ llama_sampler_min_p_backend_apply,
1877    /* .backend_set_input = */ nullptr,
1878    /* .backend_reset     = */ nullptr,
1879    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_min_p>,
1880};
1881
1882struct llama_sampler * llama_sampler_init_min_p(float p, size_t min_keep) {
1883    const bool is_empty = (p <= 0.0f);
1884
1885    if (is_empty) {
1886        return llama_sampler_init_empty("?min-p");
1887    }
1888
1889    return llama_sampler_init(
1890        /* .iface = */ &llama_sampler_min_p_i,
1891        /* .ctx   = */ new llama_sampler_min_p {
1892            ("min-p"),
1893            /* .p        = */ p,
1894            /* .min_keep = */ min_keep,
1895        }
1896    );
1897}
1898
1899// typical
1900
1901struct llama_sampler_typical {
1902    const float  p;
1903    const size_t min_keep;
1904};
1905
1906static const char * llama_sampler_typical_name(const struct llama_sampler * /*smpl*/) {
1907    return "typical";
1908}
1909
1910static void llama_sampler_typical_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
1911    auto * ctx = (llama_sampler_typical *) smpl->ctx;
1912
1913    // Reference implementation:
1914    // https://github.com/huggingface/transformers/compare/main...cimeister:typical-sampling:typical-pr
1915    if (ctx->p >= 1.0f) {
1916        return;
1917    }
1918
1919    // Compute the softmax of logits and calculate entropy
1920    llama_sampler_softmax_impl(cur_p, true);
1921
1922    float entropy = 0.0f;
1923    for (size_t i = 0; i < cur_p->size; ++i) {
1924        entropy += -cur_p->data[i].p * logf(cur_p->data[i].p);
1925    }
1926
1927    // Compute the absolute difference between negative log probability and entropy for each candidate
1928    std::vector<float> shifted_scores;
1929    for (size_t i = 0; i < cur_p->size; ++i) {
1930        float shifted_score = fabsf(-logf(cur_p->data[i].p) - entropy);
1931        shifted_scores.push_back(shifted_score);
1932    }
1933
1934    // Sort tokens based on the shifted_scores and their corresponding indices
1935    std::vector<size_t> indices(cur_p->size);
1936    std::iota(indices.begin(), indices.end(), 0);
1937
1938    std::sort(indices.begin(), indices.end(), [&](size_t a, size_t b) {
1939        return shifted_scores[a] < shifted_scores[b];
1940    });
1941
1942    // Compute the cumulative probabilities
1943    float cum_sum = 0.0f;
1944    size_t last_idx = indices.size();
1945
1946    for (size_t i = 0; i < indices.size(); ++i) {
1947        size_t idx = indices[i];
1948        cum_sum += cur_p->data[idx].p;
1949
1950        // Check if the running sum is greater than typical or if we have kept at least min_keep tokens
1951        if (cum_sum > ctx->p && (ctx->min_keep == 0 || i >= ctx->min_keep - 1)) {
1952            last_idx = i + 1;
1953            break;
1954        }
1955    }
1956
1957    // Resize the output vector to keep only the locally typical tokens
1958    std::vector<llama_token_data> cur_p_new;
1959    for (size_t i = 0; i < last_idx; ++i) {
1960        size_t idx = indices[i];
1961        cur_p_new.push_back(cur_p->data[idx]);
1962    }
1963
1964    // Replace the data in cur_p with the cur_p_new data
1965    std::copy(cur_p_new.begin(), cur_p_new.end(), cur_p->data);
1966    cur_p->size = cur_p_new.size();
1967    cur_p->sorted = false;
1968}
1969
1970static struct llama_sampler * llama_sampler_typical_clone(const struct llama_sampler * smpl) {
1971    const auto * ctx = (const llama_sampler_typical *) smpl->ctx;
1972    return llama_sampler_init_typical(ctx->p, ctx->min_keep);
1973}
1974
1975static void llama_sampler_typical_free(struct llama_sampler * smpl) {
1976    delete (llama_sampler_typical *) smpl->ctx;
1977}
1978
1979static struct llama_sampler_i llama_sampler_typical_i = {
1980    /* .name              = */ llama_sampler_typical_name,
1981    /* .accept            = */ nullptr,
1982    /* .apply             = */ llama_sampler_typical_apply,
1983    /* .reset             = */ nullptr,
1984    /* .clone             = */ llama_sampler_typical_clone,
1985    /* .free              = */ llama_sampler_typical_free,
1986    /* .backend_init      = */ nullptr,
1987    /* .backend_accept    = */ nullptr,
1988    /* .backend_apply     = */ nullptr,
1989    /* .backend_set_input = */ nullptr,
1990    /* .backend_reset     = */ nullptr,
1991    /* .copy_state        = */ nullptr,
1992};
1993
1994struct llama_sampler * llama_sampler_init_typical(float p, size_t min_keep) {
1995    const bool is_empty = (p >= 1.0f);
1996
1997    if (is_empty) {
1998        return llama_sampler_init_empty("?typical");
1999    }
2000
2001    return llama_sampler_init(
2002        /* .iface = */ &llama_sampler_typical_i,
2003        /* .ctx   = */ new llama_sampler_typical {
2004            /* .p        = */ p,
2005            /* .min_keep = */ min_keep,
2006        }
2007    );
2008}
2009
2010// temp
2011
2012struct llama_sampler_temp : public llama_sampler_backend {
2013    const float temp;
2014};
2015
2016static const char * llama_sampler_temp_name(const struct llama_sampler * smpl) {
2017    auto * sctx = (llama_sampler_temp *) smpl->ctx;
2018    return sctx->get_name();
2019}
2020
2021static void llama_sampler_temp_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2022    const auto * ctx = (llama_sampler_temp *) smpl->ctx;
2023
2024    llama_sampler_temp_impl(cur_p, ctx->temp);
2025}
2026
2027static struct llama_sampler * llama_sampler_temp_clone(const struct llama_sampler * smpl) {
2028    const auto * ctx = (const llama_sampler_temp *) smpl->ctx;
2029    return llama_sampler_init_temp(ctx->temp);
2030}
2031
2032static void llama_sampler_temp_free(struct llama_sampler * smpl) {
2033    delete (llama_sampler_temp *) smpl->ctx;
2034}
2035
2036static void llama_sampler_backend_temp_sampling(
2037        struct ggml_context       * ctx,
2038        struct ggml_cgraph        * gf,
2039        struct llama_sampler_data * data,
2040        float                       temp) {
2041    if (temp <= 0.0f) {
2042        struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
2043
2044        // Find the most probable token index.
2045        struct ggml_tensor * max_idx = ggml_argmax(ctx, logits);
2046        ggml_set_name(max_idx, "temp_max_idx");
2047
2048        if (data->candidates) {
2049            struct ggml_tensor * candidates_rows = ggml_reshape_2d(ctx, data->candidates, 1, ggml_nelements(data->candidates));
2050            data->candidates = ggml_get_rows(ctx, candidates_rows, max_idx);
2051        } else {
2052            data->candidates = max_idx;
2053        }
2054
2055        struct ggml_tensor * logits_rows = ggml_reshape_2d(ctx, logits, 1, ggml_nelements(logits));
2056        data->logits = ggml_get_rows(ctx, logits_rows, max_idx);
2057
2058        return;
2059    }
2060
2061    data->logits = ggml_scale(ctx, data->logits, 1.0f / temp);
2062
2063    GGML_UNUSED(gf);
2064}
2065
2066static bool llama_sampler_temp_backend_init(
2067        struct llama_sampler       * smpl,
2068        ggml_backend_buffer_type_t   buft,
2069        uint32_t                     n_outputs_max_per_seq) {
2070    auto * sctx = (llama_sampler_temp *) smpl->ctx;
2071    GGML_UNUSED(n_outputs_max_per_seq);
2072
2073    const bool res = llama_sampler_backend_support(smpl, buft);
2074
2075    sctx->init(res);
2076
2077    return res;
2078}
2079
2080static void llama_sampler_temp_backend_apply(
2081        struct llama_sampler      * smpl,
2082        struct ggml_context       * ctx,
2083        struct ggml_cgraph        * gf,
2084        struct llama_sampler_data * data) {
2085    auto * sctx = (llama_sampler_temp *) smpl->ctx;
2086    llama_sampler_backend_temp_sampling(ctx, gf, data, sctx->temp);
2087}
2088
2089static struct llama_sampler_i llama_sampler_temp_i = {
2090    /* .name              = */ llama_sampler_temp_name,
2091    /* .accept            = */ nullptr,
2092    /* .apply             = */ llama_sampler_temp_apply,
2093    /* .reset             = */ nullptr,
2094    /* .clone             = */ llama_sampler_temp_clone,
2095    /* .free              = */ llama_sampler_temp_free,
2096    /* .backend_init      = */ llama_sampler_temp_backend_init,
2097    /* .backend_accept    = */ nullptr,
2098    /* .backend_apply     = */ llama_sampler_temp_backend_apply,
2099    /* .backend_set_input = */ nullptr,
2100    /* .backend_reset     = */ nullptr,
2101    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_temp>,
2102};
2103
2104struct llama_sampler * llama_sampler_init_temp(float temp) {
2105    const bool is_empty = temp == 1.0f;
2106
2107    if (is_empty) {
2108        return llama_sampler_init_empty("?temp");
2109    }
2110
2111    return llama_sampler_init(
2112        /* .iface = */ &llama_sampler_temp_i,
2113        /* .ctx   = */ new llama_sampler_temp {
2114            ("temp"),
2115            /*.temp = */ temp,
2116        }
2117    );
2118}
2119
2120// temp-ext
2121
2122struct llama_sampler_temp_ext : public llama_sampler_backend {
2123    const float temp;
2124    const float delta;
2125    const float exponent;
2126};
2127
2128static const char * llama_sampler_temp_ext_name(const struct llama_sampler * smpl) {
2129    auto * sctx = (llama_sampler_temp_ext *) smpl->ctx;
2130    return sctx->get_name();
2131}
2132
2133static void llama_sampler_temp_ext_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2134    auto * ctx = (llama_sampler_temp_ext *) smpl->ctx;
2135    if (ctx->delta > 0) {
2136        const float min_temp = std::max(0.0f, ctx->temp - ctx->delta);
2137        const float max_temp = ctx->temp + ctx->delta;
2138
2139        float exponent_val = ctx->exponent;
2140
2141        // no need to do anything if there is only one (or zero) candidates
2142        if (cur_p->size <= 1) {
2143            return;
2144        }
2145
2146        // Calculate maximum possible entropy
2147        float max_entropy = -logf(1.0f / cur_p->size);
2148
2149        llama_sampler_softmax_impl(cur_p, true);
2150
2151        // Calculate entropy of the softmax probabilities
2152        float entropy = 0.0f;
2153        for (size_t i = 0; i < cur_p->size; ++i) {
2154            float prob = cur_p->data[i].p;
2155            if (prob > 0.0f) { // Ensure no log(0)
2156                entropy -= prob * logf(prob);
2157            }
2158        }
2159
2160        // Normalize the entropy (max_entropy cannot be 0 here because we checked cur_p->size != 1 above)
2161        float normalized_entropy = entropy / max_entropy;
2162
2163        // Map the normalized entropy to the desired temperature range using the power function
2164        float dyn_temp = min_temp + (max_temp - min_temp) * powf(normalized_entropy, exponent_val);
2165
2166    #ifdef DEBUG
2167        LLAMA_LOG_INFO("Your text maxtemp value is: %f\n", max_temp);
2168        LLAMA_LOG_INFO("Entropy: %f\n", entropy);
2169        LLAMA_LOG_INFO("Max Possible Entropy: %f\n", max_entropy);
2170        LLAMA_LOG_INFO("Normalized Entropy: %f\n", normalized_entropy);
2171        LLAMA_LOG_INFO("Exponent: %f\n", exponent_val);
2172        LLAMA_LOG_INFO("Dynamic Temperature (dyn_temp): %f\n", dyn_temp);
2173    #endif
2174
2175        // Apply the dynamically calculated temperature scaling
2176        llama_sampler_temp_impl(cur_p, dyn_temp);
2177
2178        // Re-compute softmax probabilities after scaling logits with dynamic temperature
2179        const double max_l_double = cur_p->data[0].logit;
2180
2181        double cum_sum_double = 0.0;
2182        for (size_t i = 0; i < cur_p->size; ++i) {
2183            double p = exp(cur_p->data[i].logit - max_l_double);
2184            cur_p->data[i].p = p; // Store the scaled probability
2185            cum_sum_double += p;
2186        }
2187
2188        for (size_t i = 0; i < cur_p->size; ++i) {
2189            cur_p->data[i].p /= cum_sum_double; // Re-normalize the probabilities
2190        }
2191
2192    #ifdef DEBUG
2193        // Print the updated top 25 probabilities after temperature scaling
2194        LLAMA_LOG_INFO("\nUpdated Top 25 Probabilities After Dynamic Temperature Scaling (in percentages):\n");
2195        for (size_t i = 0; i < 25 && i < cur_p->size; ++i) {
2196            LLAMA_LOG_INFO("Token %zu: %f%%\n", i + 1, cur_p->data[i].p * 100.0f);
2197        }
2198    #endif
2199    } else {
2200        llama_sampler_temp_impl(cur_p, ctx->temp);
2201    }
2202}
2203
2204static struct llama_sampler * llama_sampler_temp_ext_clone(const struct llama_sampler * smpl) {
2205    const auto * ctx = (const llama_sampler_temp_ext *) smpl->ctx;
2206    return llama_sampler_init_temp_ext(ctx->temp, ctx->delta, ctx->exponent);
2207}
2208
2209static void llama_sampler_temp_ext_free(struct llama_sampler * smpl) {
2210    delete (llama_sampler_temp_ext *) smpl->ctx;
2211}
2212
2213static bool llama_sampler_temp_ext_backend_init(
2214        struct llama_sampler       * smpl,
2215        ggml_backend_buffer_type_t   buft,
2216        uint32_t                     n_outputs_max_per_seq) {
2217    auto * sctx = (llama_sampler_temp_ext *) smpl->ctx;
2218    GGML_UNUSED(n_outputs_max_per_seq);
2219
2220    const bool res = llama_sampler_backend_support(smpl, buft);
2221
2222    sctx->init(res);
2223
2224    return res;
2225}
2226
2227static void llama_sampler_temp_ext_backend_apply(
2228        struct llama_sampler      * smpl,
2229        struct ggml_context       * ctx,
2230        struct ggml_cgraph        * gf,
2231        struct llama_sampler_data * data) {
2232    auto * sctx = (llama_sampler_temp_ext *) smpl->ctx;
2233
2234    // Revert to standard temperature scaling if delta or temp are non-positive.
2235    if (sctx->delta <= 0.0f || sctx->temp <= 0.0f) {
2236        llama_sampler_backend_temp_sampling(ctx, gf, data, sctx->temp);
2237        return;
2238    }
2239
2240    struct ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
2241
2242    // Calculate min_temp, max_temp, and max_entropy.
2243    const float min_temp    = std::max(0.0f, sctx->temp - sctx->delta);
2244    const float max_temp    = sctx->temp + sctx->delta;
2245    const float max_entropy = logf(logits->ne[0]);
2246
2247    // Calculate the probabilities.
2248    struct ggml_tensor * probs = ggml_soft_max(ctx, logits);
2249    ggml_set_name(probs, "temp_ext_softmax_probs");
2250
2251    // Clamp probabilities to avoid log(0) which would give -inf
2252    struct ggml_tensor * probs_clamped = ggml_clamp(ctx, probs, 1e-10f, 1.0f);
2253    ggml_set_name(probs_clamped, "temp_ext_probs_clamped");
2254
2255    // Calculate the entropy, entropy = -Σ(p * log(p)).
2256    struct ggml_tensor * log_probs   = ggml_log(ctx, probs_clamped);
2257    struct ggml_tensor * p_log_p     = ggml_mul(ctx, probs_clamped, log_probs);
2258    struct ggml_tensor * sum_p_log_p = ggml_sum(ctx, p_log_p);
2259    struct ggml_tensor * entropy     = ggml_scale(ctx, sum_p_log_p, -1.0f);
2260    ggml_set_name(log_probs,   "temp_ext_log_probs");
2261    ggml_set_name(p_log_p,     "temp_ext_p_log_p");
2262    ggml_set_name(sum_p_log_p, "temp_ext_sum_p_log_p");
2263    ggml_set_name(entropy,     "temp_ext_entropy");
2264
2265    // Normalize the entropy, norm_entropy = entropy / max_entropy
2266    struct ggml_tensor * norm_entropy = ggml_scale(ctx, entropy, 1.0f / max_entropy);
2267    ggml_set_name(norm_entropy, "temp_ext_norm_entropy");
2268
2269    // Calculate the dynamic temperature:
2270    // dyn_temp = min_temp + (max_temp - min_temp) * powf(normalized_entropy, exponent);
2271    //
2272    // Calculate powf(normalized_entropy, exponent) as
2273    // norm_entropy^exponent = exp(exponent * log(norm_entropy))
2274    struct ggml_tensor * log_norm_entropy = ggml_log(ctx, norm_entropy);
2275    struct ggml_tensor * scaled_log       = ggml_scale(ctx, log_norm_entropy, sctx->exponent);
2276    struct ggml_tensor * pow_entropy      = ggml_exp(ctx, scaled_log);
2277    // With pow_entropy computed we can now compute dyn_temp, scaling by
2278    // (max_temp - min_temp) and then adding min_temp.
2279    struct ggml_tensor * dyn_temp         = ggml_scale_bias(ctx, pow_entropy, max_temp - min_temp, min_temp);
2280    ggml_set_name(log_norm_entropy, "temp_ext_log_norm_entropy");
2281    ggml_set_name(scaled_log,       "temp_ext_scaled_log");
2282    ggml_set_name(pow_entropy,      "temp_ext_pow_entropy");
2283    ggml_set_name(dyn_temp,         "temp_ext_dyn_temp");
2284
2285    // Scale the logits by the dynamic temperature
2286    struct ggml_tensor * scaled_logits = ggml_div(ctx, logits, dyn_temp);
2287    ggml_set_name(scaled_logits, "temp_ext_scaled_logits");
2288
2289    data->logits = scaled_logits;
2290}
2291
2292static struct llama_sampler_i llama_sampler_temp_ext_i = {
2293    /* .name              = */ llama_sampler_temp_ext_name,
2294    /* .accept            = */ nullptr,
2295    /* .apply             = */ llama_sampler_temp_ext_apply,
2296    /* .reset             = */ nullptr,
2297    /* .clone             = */ llama_sampler_temp_ext_clone,
2298    /* .free              = */ llama_sampler_temp_ext_free,
2299    /* .backend_init      = */ llama_sampler_temp_ext_backend_init,
2300    /* .backend_accept    = */ nullptr,
2301    /* .backend_apply     = */ llama_sampler_temp_ext_backend_apply,
2302    /* .backend_set_input = */ nullptr,
2303    /* .backend_reset     = */ nullptr,
2304    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_temp_ext>,
2305};
2306
2307struct llama_sampler * llama_sampler_init_temp_ext(float temp, float delta, float exponent) {
2308    const bool is_empty = temp == 1.0f && delta <= 0.0f;
2309
2310    if (is_empty) {
2311        return llama_sampler_init_empty("?temp-ext");
2312    }
2313
2314    auto * res = llama_sampler_init(
2315        /* .iface = */ &llama_sampler_temp_ext_i,
2316        /* .ctx   = */ new llama_sampler_temp_ext {
2317            ("temp-ext"),
2318            /* .temp     = */ temp,
2319            /* .delta    = */ delta,
2320            /* .exponent = */ exponent,
2321        }
2322    );
2323
2324    return res;
2325}
2326
2327// xtc
2328
2329struct llama_sampler_xtc {
2330    const float    probability;
2331    const float    threshold;
2332    const size_t   min_keep;
2333
2334    const uint32_t seed;
2335    uint32_t       seed_cur;
2336
2337    std::mt19937   rng;
2338};
2339
2340static const char * llama_sampler_xtc_name(const struct llama_sampler * /*smpl*/) {
2341    return "xtc";
2342}
2343
2344static void llama_sample_xtc_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2345    auto * ctx = (llama_sampler_xtc *) smpl->ctx;
2346
2347    if (ctx->probability <= 0.0f
2348        || ctx->threshold > 0.5f
2349        || cur_p->size < 2) {
2350        return;
2351    }
2352
2353    std::uniform_real_distribution<float> distribution(0.0f, 1.0f);
2354    float chance = distribution(ctx->rng);
2355    if (chance > ctx->probability) {
2356        return;
2357    }
2358
2359    llama_sampler_softmax_impl(cur_p, true);
2360
2361    int pos_last = 0;
2362
2363    for (size_t i = 0; i < cur_p->size; ++i) {
2364        if (cur_p->data[i].p >= ctx->threshold) {
2365            pos_last = i;
2366        } else {
2367            break;
2368        }
2369    }
2370
2371    if (cur_p->size - pos_last >= ctx->min_keep && pos_last > 0) {
2372        cur_p->data += pos_last;
2373        cur_p->size -= pos_last;
2374    }
2375}
2376
2377static struct llama_sampler * llama_sampler_xtc_clone(const struct llama_sampler * smpl) {
2378    const auto * ctx = (const llama_sampler_xtc *) smpl->ctx;
2379    auto * result = llama_sampler_init_xtc(ctx->probability, ctx->threshold, ctx->min_keep, ctx->seed);
2380
2381    // copy the state
2382    {
2383        auto * result_ctx = (llama_sampler_xtc *) result->ctx;
2384
2385        result_ctx->rng = ctx->rng;
2386    }
2387
2388    return result;
2389}
2390
2391static void llama_sampler_xtc_free(struct llama_sampler * smpl) {
2392    delete (llama_sampler_xtc *) smpl->ctx;
2393}
2394
2395static void llama_sampler_xtc_reset(struct llama_sampler * smpl) {
2396    auto * ctx = (llama_sampler_xtc *) smpl->ctx;
2397    ctx->seed_cur = get_rng_seed(ctx->seed);
2398    ctx->rng.seed(ctx->seed_cur);
2399}
2400
2401static struct llama_sampler_i llama_sampler_xtc_i = {
2402    /* .name              = */ llama_sampler_xtc_name,
2403    /* .accept            = */ nullptr,
2404    /* .apply             = */ llama_sample_xtc_apply,
2405    /* .reset             = */ llama_sampler_xtc_reset,
2406    /* .clone             = */ llama_sampler_xtc_clone,
2407    /* .free              = */ llama_sampler_xtc_free,
2408    /* .backend_init      = */ nullptr,
2409    /* .backend_accept    = */ nullptr,
2410    /* .backend_apply     = */ nullptr,
2411    /* .backend_set_input = */ nullptr,
2412    /* .backend_reset     = */ nullptr,
2413    /* .copy_state        = */ nullptr,
2414};
2415
2416struct llama_sampler * llama_sampler_init_xtc(float p, float t, size_t min_keep, uint32_t seed) {
2417    const bool is_empty = (p <= 0.0f || t > 0.5f);
2418
2419    if (is_empty) {
2420        return llama_sampler_init_empty("?xtc");
2421    }
2422
2423    const auto seed_cur = get_rng_seed(seed);
2424
2425    return llama_sampler_init(
2426        /* .iface = */ &llama_sampler_xtc_i,
2427        /* .ctx   = */ new llama_sampler_xtc {
2428            /* .probability   = */ p,
2429            /* .threshold     = */ t,
2430            /* .min_keep      = */ min_keep,
2431            /* .seed          = */ seed,
2432            /* .seed_cur      = */ seed_cur,
2433            /* .rng           = */ std::mt19937(seed_cur),
2434        }
2435    );
2436}
2437
2438// mirostat
2439
2440struct llama_sampler_mirostat {
2441    const int32_t n_vocab;
2442
2443    const uint32_t seed;
2444          uint32_t seed_cur;
2445
2446    const float tau;
2447    const float eta;
2448
2449    const int32_t m;
2450
2451    float mu;
2452
2453    std::mt19937    rng;
2454};
2455
2456static const char * llama_sampler_mirostat_name(const struct llama_sampler * /*smpl*/) {
2457    return "mirostat";
2458}
2459
2460static void llama_sampler_mirostat_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2461    auto * ctx = (llama_sampler_mirostat *) smpl->ctx;
2462
2463    llama_sampler_softmax_impl(cur_p, true);
2464
2465    // Estimate s_hat using the most probable m tokens
2466    float s_hat = 0.0;
2467    float sum_ti_bi = 0.0;
2468    float sum_ti_sq = 0.0;
2469    for (size_t i = 0; i < size_t(ctx->m - 1) && i < cur_p->size - 1; ++i) {
2470        float t_i = logf(float(i + 2) / float(i + 1));
2471        float b_i = logf(cur_p->data[i].p / cur_p->data[i + 1].p);
2472        sum_ti_bi += t_i * b_i;
2473        sum_ti_sq += t_i * t_i;
2474    }
2475    s_hat = sum_ti_bi / sum_ti_sq;
2476
2477    // Compute k from the estimated s_hat and target surprise value
2478    float epsilon_hat = s_hat - 1;
2479    float k = powf((epsilon_hat * powf(2, ctx->mu)) / (1 - powf(ctx->n_vocab, -epsilon_hat)), 1 / s_hat);
2480
2481    llama_sampler_top_k_impl(cur_p, std::max(int(k), 1));
2482
2483    llama_sampler_softmax_impl(cur_p, true);
2484
2485    const int idx = llama_sample_dist(cur_p, ctx->rng);
2486
2487    cur_p->selected = idx;
2488
2489    float observed_surprise = -log2f(cur_p->data[idx].p);
2490    float e = observed_surprise - ctx->tau;
2491
2492    // Update mu using the learning rate and error
2493    ctx->mu = ctx->mu - ctx->eta * e;
2494}
2495
2496static struct llama_sampler * llama_sampler_mirostat_clone(const struct llama_sampler * smpl) {
2497    const auto * ctx = (const llama_sampler_mirostat *) smpl->ctx;
2498    auto * result = llama_sampler_init_mirostat(ctx->n_vocab, ctx->seed, ctx->tau, ctx->eta, ctx->m);
2499
2500    // copy the state
2501    {
2502        auto * result_ctx = (llama_sampler_mirostat *) result->ctx;
2503
2504        result_ctx->mu  = ctx->mu;
2505        result_ctx->rng = ctx->rng;
2506    }
2507
2508    return result;
2509}
2510
2511static void llama_sampler_mirostat_reset(struct llama_sampler * smpl) {
2512    auto * ctx = (llama_sampler_mirostat *) smpl->ctx;
2513    ctx->mu = 2.0f*ctx->tau;
2514    ctx->seed_cur = get_rng_seed(ctx->seed);
2515    ctx->rng.seed(ctx->seed_cur);
2516}
2517
2518static void llama_sampler_mirostat_free(struct llama_sampler * smpl) {
2519    delete (llama_sampler_mirostat *) smpl->ctx;
2520}
2521
2522static struct llama_sampler_i llama_sampler_mirostat_i = {
2523    /* .name              = */ llama_sampler_mirostat_name,
2524    /* .accept            = */ nullptr,
2525    /* .apply             = */ llama_sampler_mirostat_apply,
2526    /* .reset             = */ llama_sampler_mirostat_reset,
2527    /* .clone             = */ llama_sampler_mirostat_clone,
2528    /* .free              = */ llama_sampler_mirostat_free,
2529    /* .backend_init      = */ nullptr,
2530    /* .backend_accept    = */ nullptr,
2531    /* .backend_apply     = */ nullptr,
2532    /* .backend_set_input = */ nullptr,
2533    /* .backend_reset     = */ nullptr,
2534    /* .copy_state        = */ nullptr,
2535};
2536
2537struct llama_sampler * llama_sampler_init_mirostat(int32_t n_vocab, uint32_t seed, float tau, float eta, int32_t m) {
2538    const auto seed_cur = get_rng_seed(seed);
2539
2540    return llama_sampler_init(
2541        /* .iface = */ &llama_sampler_mirostat_i,
2542        /* .ctx   = */ new llama_sampler_mirostat {
2543            /* .n_vocab  = */ n_vocab,
2544            /* .seed     = */ seed,
2545            /* .seed_cur = */ seed_cur,
2546            /* .tau      = */ tau,
2547            /* .eta      = */ eta,
2548            /* .m        = */ m,
2549            /* .mu       = */ 2.0f*tau,
2550            /* .rng      = */ std::mt19937(seed_cur),
2551        }
2552    );
2553}
2554
2555// mirostat v2
2556
2557struct llama_sampler_mirostat_v2 {
2558    const uint32_t seed;
2559          uint32_t seed_cur;
2560
2561    const float tau;
2562    const float eta;
2563
2564    float mu;
2565
2566    std::mt19937 rng;
2567};
2568
2569static const char * llama_sampler_mirostat_v2_name(const struct llama_sampler * /*smpl*/) {
2570    return "mirostat-v2";
2571}
2572
2573static void llama_sampler_mirostat_v2_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2574    auto * ctx = (llama_sampler_mirostat_v2 *) smpl->ctx;
2575
2576    llama_sampler_softmax_impl(cur_p, true);
2577
2578    // Truncate the words with surprise values greater than mu
2579    cur_p->size = std::distance(cur_p->data, std::find_if(cur_p->data, cur_p->data + cur_p->size, [&](const llama_token_data & candidate) {
2580        return -log2f(candidate.p) > ctx->mu;
2581    }));
2582
2583    if (cur_p->size == 0) {
2584        cur_p->size = 1;
2585    }
2586
2587    // Normalize the probabilities of the remaining words
2588    llama_sampler_softmax_impl(cur_p, true);
2589
2590    const int idx = llama_sample_dist(cur_p, ctx->rng);
2591
2592    cur_p->selected = idx;
2593
2594    float observed_surprise = -log2f(cur_p->data[idx].p);
2595    float e = observed_surprise - ctx->tau;
2596
2597    // Update mu using the learning rate and error
2598    ctx->mu = ctx->mu - ctx->eta * e;
2599}
2600
2601static void llama_sampler_mirostat_v2_reset(struct llama_sampler * smpl) {
2602    auto * ctx = (llama_sampler_mirostat_v2 *) smpl->ctx;
2603    ctx->mu = 2.0f*ctx->tau;
2604    ctx->seed_cur = get_rng_seed(ctx->seed);
2605    ctx->rng.seed(ctx->seed_cur);
2606}
2607
2608static struct llama_sampler * llama_sampler_mirostat_v2_clone(const struct llama_sampler * smpl) {
2609    const auto * ctx = (const llama_sampler_mirostat_v2 *) smpl->ctx;
2610
2611    auto * result = llama_sampler_init_mirostat_v2(ctx->seed, ctx->tau, ctx->eta);
2612
2613    // copy the state
2614    {
2615        auto * result_ctx = (llama_sampler_mirostat_v2 *) result->ctx;
2616
2617        result_ctx->mu  = ctx->mu;
2618        result_ctx->rng = ctx->rng;
2619    }
2620
2621    return result;
2622}
2623
2624static void llama_sampler_mirostat_v2_free(struct llama_sampler * smpl) {
2625    delete (llama_sampler_mirostat_v2 *) smpl->ctx;
2626}
2627
2628static struct llama_sampler_i llama_sampler_mirostat_v2_i = {
2629    /* .name              = */ llama_sampler_mirostat_v2_name,
2630    /* .accept            = */ nullptr,
2631    /* .apply             = */ llama_sampler_mirostat_v2_apply,
2632    /* .reset             = */ llama_sampler_mirostat_v2_reset,
2633    /* .clone             = */ llama_sampler_mirostat_v2_clone,
2634    /* .free              = */ llama_sampler_mirostat_v2_free,
2635    /* .backend_init      = */ nullptr,
2636    /* .backend_accept    = */ nullptr,
2637    /* .backend_apply     = */ nullptr,
2638    /* .backend_set_input = */ nullptr,
2639    /* .backend_reset     = */ nullptr,
2640    /* .copy_state        = */ nullptr,
2641};
2642
2643struct llama_sampler * llama_sampler_init_mirostat_v2(uint32_t seed, float tau, float eta) {
2644    auto seed_cur = get_rng_seed(seed);
2645    return llama_sampler_init(
2646        /* .iface = */ &llama_sampler_mirostat_v2_i,
2647        /* .ctx   = */ new llama_sampler_mirostat_v2 {
2648            /* .seed     = */ seed,
2649            /* .seed_cur = */ seed_cur,
2650            /* .tau      = */ tau,
2651            /* .eta      = */ eta,
2652            /* .mu       = */ 2.0f*tau,
2653            /* .rng      = */ std::mt19937(seed_cur),
2654        }
2655    );
2656}
2657
2658// grammar
2659
2660struct llama_sampler_grammar {
2661    const struct llama_vocab * vocab;
2662
2663    std::string grammar_str;
2664    std::string grammar_root;
2665
2666    struct llama_grammar * grammar;
2667};
2668
2669static const char * llama_sampler_grammar_name(const struct llama_sampler * /*smpl*/) {
2670    return "grammar";
2671}
2672
2673static void llama_sampler_grammar_accept_impl(struct llama_sampler * smpl, llama_token token) {
2674    auto * ctx = (llama_sampler_grammar *) smpl->ctx;
2675    if (ctx->grammar) {
2676        llama_grammar_accept_impl(*ctx->grammar, token);
2677    }
2678}
2679
2680static void llama_sampler_grammar_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2681    auto * ctx = (llama_sampler_grammar *) smpl->ctx;
2682    if (ctx->grammar) {
2683        llama_grammar_apply_impl(*ctx->grammar, cur_p);
2684    }
2685}
2686
2687// Fwd declare to break reset --> init_impl --> llama_sampler_grammar_i --> reset cycle.
2688static struct llama_sampler * llama_sampler_init_grammar_impl(
2689        const struct llama_vocab * vocab,
2690                      const char * grammar_str,
2691                      const char * grammar_root,
2692                              bool lazy,
2693                     const char ** trigger_words,
2694                            size_t num_trigger_words,
2695               const llama_token * trigger_tokens,
2696                            size_t num_trigger_tokens,
2697                     const char ** trigger_patterns,
2698                            size_t num_trigger_patterns);
2699
2700static void llama_sampler_grammar_reset(struct llama_sampler * smpl) {
2701    auto * ctx = (llama_sampler_grammar *) smpl->ctx;
2702    if (!ctx->grammar) {
2703        return;
2704    }
2705
2706    std::vector<const char *>  trigger_patterns_c;
2707    trigger_patterns_c.reserve(ctx->grammar->trigger_patterns.size());
2708    for (auto & trigger_pattern : ctx->grammar->trigger_patterns) {
2709        trigger_patterns_c.push_back(trigger_pattern.pattern.c_str());
2710    }
2711
2712    auto * grammar_new = llama_grammar_init_impl(ctx->grammar->vocab, ctx->grammar_str.c_str(), ctx->grammar_root.c_str(),
2713                                                 ctx->grammar->lazy, trigger_patterns_c.data(), trigger_patterns_c.size(),
2714                                                 ctx->grammar->trigger_tokens.data(), ctx->grammar->trigger_tokens.size());
2715
2716    llama_grammar_free_impl(ctx->grammar);
2717    ctx->grammar = grammar_new;
2718}
2719
2720static struct llama_sampler * llama_sampler_grammar_clone(const struct llama_sampler * smpl) {
2721    const auto * ctx = (const llama_sampler_grammar *) smpl->ctx;
2722
2723    auto * result = llama_sampler_init_grammar_impl(ctx->vocab, nullptr, nullptr, false, nullptr, 0, nullptr, 0, nullptr, 0);
2724    GGML_ASSERT(result);
2725
2726    // copy the state
2727    {
2728        auto * result_ctx = (llama_sampler_grammar *) result->ctx;
2729
2730        if (ctx->grammar) {
2731            result_ctx->grammar_str  = ctx->grammar_str;
2732            result_ctx->grammar_root = ctx->grammar_root;
2733
2734            result_ctx->grammar = llama_grammar_clone_impl(*ctx->grammar);
2735        }
2736    }
2737
2738    return result;
2739}
2740
2741static void llama_sampler_grammar_free(struct llama_sampler * smpl) {
2742    const auto * ctx = (llama_sampler_grammar *) smpl->ctx;
2743
2744    if (ctx->grammar) {
2745        llama_grammar_free_impl(ctx->grammar);
2746    }
2747
2748    delete ctx;
2749}
2750
2751static struct llama_sampler_i llama_sampler_grammar_i = {
2752    /* .name              = */ llama_sampler_grammar_name,
2753    /* .accept            = */ llama_sampler_grammar_accept_impl,
2754    /* .apply             = */ llama_sampler_grammar_apply,
2755    /* .reset             = */ llama_sampler_grammar_reset,
2756    /* .clone             = */ llama_sampler_grammar_clone,
2757    /* .free              = */ llama_sampler_grammar_free,
2758    /* .backend_init      = */ nullptr,
2759    /* .backend_accept    = */ nullptr,
2760    /* .backend_apply     = */ nullptr,
2761    /* .backend_set_input = */ nullptr,
2762    /* .backend_reset     = */ nullptr,
2763    /* .copy_state        = */ nullptr,
2764};
2765
2766static struct llama_sampler * llama_sampler_init_grammar_impl(
2767        const struct llama_vocab * vocab,
2768                      const char * grammar_str,
2769                      const char * grammar_root,
2770                              bool lazy,
2771                     const char ** trigger_words,
2772                            size_t num_trigger_words,
2773               const llama_token * trigger_tokens,
2774                            size_t num_trigger_tokens,
2775                     const char ** trigger_patterns,
2776                            size_t num_trigger_patterns) {
2777    auto * ctx = new llama_sampler_grammar;
2778
2779    if (grammar_str != nullptr && grammar_str[0] != '\0') {
2780        std::string trigger_pattern;
2781        llama_grammar * grammar = nullptr;
2782        // TODO: remove trigger_words support.
2783        if (trigger_words != nullptr && num_trigger_words > 0) {
2784            GGML_ASSERT(trigger_patterns == nullptr && num_trigger_patterns == 0);
2785            trigger_pattern = "[\\s\\S]*?(";
2786            for (size_t i = 0; i < num_trigger_words; ++i) {
2787                static const std::regex special_chars("[.^$|()*+?\\[\\]{}\\\\]");
2788                if (i > 0) {
2789                    trigger_pattern += "|";
2790                }
2791                trigger_pattern += std::regex_replace(trigger_words[i], special_chars, "\\$0");
2792            }
2793            trigger_pattern += ")[\\s\\S]*";
2794
2795            std::array<const char *, 1> tmp_trigger_patterns = { trigger_pattern.c_str() };
2796            grammar = llama_grammar_init_impl(vocab, grammar_str, grammar_root, lazy, tmp_trigger_patterns.data(), tmp_trigger_patterns.size(), trigger_tokens, num_trigger_tokens);
2797        } else {
2798            grammar = llama_grammar_init_impl(vocab, grammar_str, grammar_root, lazy, trigger_patterns, num_trigger_patterns, trigger_tokens, num_trigger_tokens);
2799        }
2800        *ctx = {
2801            /* .vocab        = */ vocab,
2802            /* .grammar_str  = */ grammar_str,
2803            /* .grammar_root = */ grammar_root,
2804            /* .grammar      = */ grammar,
2805        };
2806        if (!ctx->grammar) {
2807            delete ctx;
2808            return nullptr;
2809        }
2810    } else {
2811        *ctx = {
2812            /* .vocab        = */ vocab,
2813            /* .grammar_str  = */ {},
2814            /* .grammar_root = */ {},
2815            /* .grammar      = */ nullptr,
2816        };
2817    }
2818
2819    return llama_sampler_init(
2820        /* .iface = */ &llama_sampler_grammar_i,
2821        /* .ctx   = */ ctx
2822    );
2823}
2824
2825struct llama_sampler * llama_sampler_init_grammar(
2826        const struct llama_vocab * vocab,
2827                      const char * grammar_str,
2828                      const char * grammar_root) {
2829    return llama_sampler_init_grammar_impl(vocab, grammar_str, grammar_root, /* lazy= */ false, nullptr, 0, nullptr, 0, nullptr, 0);
2830}
2831
2832struct llama_sampler * llama_sampler_init_grammar_lazy(
2833        const struct llama_vocab * vocab,
2834                      const char * grammar_str,
2835                      const char * grammar_root,
2836                     const char ** trigger_words,
2837                            size_t num_trigger_words,
2838               const llama_token * trigger_tokens,
2839                            size_t num_trigger_tokens) {
2840    return llama_sampler_init_grammar_impl(vocab, grammar_str, grammar_root, /* lazy= */ true, trigger_words, num_trigger_words, trigger_tokens, num_trigger_tokens, nullptr, 0);
2841}
2842
2843struct llama_sampler * llama_sampler_init_grammar_lazy_patterns(
2844        const struct llama_vocab * vocab,
2845                      const char * grammar_str,
2846                      const char * grammar_root,
2847                     const char ** trigger_patterns,
2848                            size_t num_trigger_patterns,
2849               const llama_token * trigger_tokens,
2850                            size_t num_trigger_tokens) {
2851    return llama_sampler_init_grammar_impl(vocab, grammar_str, grammar_root, /* lazy= */ true, nullptr, 0, trigger_tokens, num_trigger_tokens, trigger_patterns, num_trigger_patterns);
2852}
2853
2854// penalties
2855
2856struct llama_sampler_penalties : public llama_sampler_backend {
2857    const int32_t n_vocab;
2858    const int32_t penalty_last_n;
2859    const float   penalty_repeat;
2860    const float   penalty_freq;
2861    const float   penalty_present;
2862
2863    ring_buffer<llama_token> prev;
2864
2865    // a frequency map to count token occurrences
2866    std::unordered_map<llama_token, int> token_count;
2867
2868    // backend graph inputs
2869    ggml_tensor * inp_token_ids = nullptr;
2870    ggml_tensor * inp_counts    = nullptr;
2871
2872    // backend helpers
2873    int32_t n_max   = 0;
2874    bool has_candidates = false;
2875
2876    std::vector<int32_t> host_token_ids;
2877    std::vector<int32_t> host_counts;
2878
2879    void copy_state(const llama_sampler_penalties & src) {
2880        // note: inp_token_ids/inp_counts belong to the current sampling graph
2881        prev        = src.prev;
2882        token_count = src.token_count;
2883    }
2884
2885    static bool is_disabled(
2886            int32_t penalty_last_n,
2887            float   penalty_repeat,
2888            float   penalty_freq,
2889            float   penalty_present) {
2890        return penalty_last_n == 0 ||
2891            (penalty_repeat == 1.0f && penalty_freq == 0.0f && penalty_present == 0.0f);
2892    }
2893
2894    bool is_disabled() const {
2895        return is_disabled(penalty_last_n, penalty_repeat, penalty_freq, penalty_present);
2896    }
2897
2898    llama_sampler_penalties(
2899            int32_t n_vocab,
2900            int32_t penalty_last_n,
2901            float   penalty_repeat,
2902            float   penalty_freq,
2903            float   penalty_present)
2904        : llama_sampler_backend("penalties")
2905        , n_vocab         (n_vocab)
2906        , penalty_last_n  (penalty_last_n)
2907        , penalty_repeat  (penalty_repeat)
2908        , penalty_freq    (penalty_freq)
2909        , penalty_present (penalty_present)
2910        , prev            (penalty_last_n) {
2911    }
2912};
2913
2914static const char * llama_sampler_penalties_name(const struct llama_sampler * smpl) {
2915    auto * ctx = (llama_sampler_penalties *) smpl->ctx;
2916    return ctx->get_name();
2917}
2918
2919static void llama_sampler_penalties_accept(struct llama_sampler * smpl, llama_token token) {
2920    auto * ctx = (llama_sampler_penalties *) smpl->ctx;
2921    if (ctx->penalty_last_n == 0) {
2922        return;
2923    }
2924
2925    ctx->token_count[token]++;
2926
2927    // if the ring buffer is full, remove the oldest token
2928    if (ctx->prev.size() >= (size_t) ctx->penalty_last_n) {
2929        const auto old = ctx->prev.front();
2930
2931        ctx->token_count[old]--;
2932        if (ctx->token_count[old] == 0) {
2933            ctx->token_count.erase(old);
2934        }
2935    }
2936
2937    ctx->prev.push_back(token);
2938
2939#if 0
2940    // sanity check
2941    std::unordered_map<llama_token, int> tmp;
2942    for (int i = 0; i < std::min<int>(ctx->penalty_last_n, ctx->prev.size()); ++i) {
2943        tmp[ctx->prev.rat(i)]++;
2944    }
2945
2946    assert(ctx->token_count == tmp);
2947#endif
2948}
2949
2950static void llama_sampler_penalties_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
2951    auto * ctx = (llama_sampler_penalties *) smpl->ctx;
2952
2953    if (ctx->is_disabled()) {
2954        return;
2955    }
2956
2957    // Apply frequency and presence penalties to the cur_p
2958    for (size_t i = 0; i < cur_p->size; ++i) {
2959        const auto token_iter = ctx->token_count.find(cur_p->data[i].id);
2960        if (token_iter == ctx->token_count.end()) {
2961            continue;
2962        }
2963
2964        const int count = token_iter->second;
2965
2966        assert(count > 0 && count <= ctx->penalty_last_n);
2967
2968        // The academic publication that described this technique actually just only divided, but that would cause tokens with negative logits to become more likely, which is obviously wrong.
2969        // This is common fix for this problem, which is to multiply by the penalty instead of dividing.
2970        if (cur_p->data[i].logit <= 0) {
2971            cur_p->data[i].logit *= ctx->penalty_repeat;
2972        } else {
2973            cur_p->data[i].logit /= ctx->penalty_repeat;
2974        }
2975
2976        cur_p->data[i].logit -= float(count) * ctx->penalty_freq + float(count > 0) * ctx->penalty_present;
2977    }
2978
2979    cur_p->sorted = false;
2980}
2981
2982static void llama_sampler_penalties_reset(struct llama_sampler * smpl) {
2983    auto * ctx = (llama_sampler_penalties *) smpl->ctx;
2984    ctx->prev.clear();
2985    ctx->token_count.clear();
2986}
2987
2988static struct llama_sampler * llama_sampler_penalties_clone(const struct llama_sampler * smpl) {
2989    const auto * ctx = (const llama_sampler_penalties *) smpl->ctx;
2990    auto * result = llama_sampler_init_penalties(
2991            ctx->n_vocab,
2992            ctx->penalty_last_n,
2993            ctx->penalty_repeat,
2994            ctx->penalty_freq,
2995            ctx->penalty_present);
2996
2997    // copy the state
2998    {
2999        auto * result_ctx = (llama_sampler_penalties *) result->ctx;
3000
3001        result_ctx->prev        = ctx->prev;
3002        result_ctx->token_count = ctx->token_count;
3003    }
3004
3005    return result;
3006}
3007
3008static void llama_sampler_penalties_free(struct llama_sampler * smpl) {
3009    delete (llama_sampler_penalties *) smpl->ctx;
3010}
3011
3012static bool llama_sampler_penalties_backend_init(
3013        struct llama_sampler       * smpl,
3014        ggml_backend_buffer_type_t   buft,
3015        uint32_t                     n_outputs_max_per_seq) {
3016    auto * sctx = (llama_sampler_penalties *) smpl->ctx;
3017
3018    if (n_outputs_max_per_seq > 1) {
3019        sctx->init(false);
3020        return false;
3021    }
3022
3023    const bool res = llama_sampler_backend_support(smpl, buft);
3024
3025    sctx->init(res);
3026
3027    return res;
3028}
3029
3030static void llama_sampler_penalties_backend_apply(
3031        struct llama_sampler      * smpl,
3032        struct ggml_context       * ctx,
3033        struct ggml_cgraph        * gf,
3034        struct llama_sampler_data * data) {
3035    GGML_UNUSED(gf);
3036
3037    auto * sctx = (llama_sampler_penalties *) smpl->ctx;
3038
3039    if (sctx->is_disabled()) {
3040        return;
3041    }
3042
3043    GGML_ASSERT(sctx->n_vocab > 0);
3044
3045    sctx->has_candidates = data->candidates != nullptr;
3046    sctx->n_max   = std::min(sctx->penalty_last_n, sctx->n_vocab);
3047
3048    sctx->inp_token_ids = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, sctx->n_max);
3049    ggml_set_name(sctx->inp_token_ids, "penalties_token_ids");
3050    ggml_set_input(sctx->inp_token_ids);
3051
3052    sctx->inp_counts = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, sctx->n_max);
3053    ggml_set_name(sctx->inp_counts, "penalties_counts");
3054    ggml_set_input(sctx->inp_counts);
3055
3056    if ((int32_t) sctx->host_token_ids.size() != sctx->n_max) {
3057        sctx->host_token_ids.assign(sctx->n_max, 0);
3058        sctx->host_counts.assign(sctx->n_max, 0);
3059    }
3060
3061    // flatten
3062    ggml_tensor * logits = ggml_reshape_1d(ctx, data->logits, ggml_nelements(data->logits));
3063    ggml_tensor * gathered = logits;
3064    ggml_tensor * counts_f32 = ggml_cast(ctx, sctx->inp_counts, GGML_TYPE_F32);
3065
3066    if (sctx->has_candidates) {
3067        ggml_tensor * candidates = ggml_reshape_1d(
3068                ctx, data->candidates, ggml_nelements(data->candidates));
3069        const int64_t n_candidates = candidates->ne[0];
3070        GGML_ASSERT(n_candidates == ggml_nelements(logits));
3071
3072        ggml_tensor * counts_rows = ggml_fill(
3073                ctx, ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 1, sctx->n_vocab), 0.0f);
3074        ggml_tensor * scatter_rows = ggml_reshape_2d(ctx, counts_f32, 1, sctx->n_max);
3075        counts_rows = ggml_set_rows(ctx, counts_rows, scatter_rows, sctx->inp_token_ids);
3076        counts_f32 = ggml_get_rows(ctx, counts_rows, candidates);
3077        counts_f32 = ggml_reshape_1d(ctx, counts_f32, n_candidates);
3078    } else {
3079        ggml_tensor * logits_rows = ggml_reshape_2d(ctx, logits, 1, ggml_nelements(logits));
3080        gathered = ggml_get_rows(ctx, logits_rows, sctx->inp_token_ids);
3081        gathered = ggml_reshape_1d(ctx, gathered, sctx->n_max);
3082    }
3083
3084    ggml_tensor * active_mask = ggml_step(ctx, counts_f32);
3085    ggml_tensor * inactive_mask = ggml_sub(ctx, ggml_fill(ctx, active_mask, 1.0f), active_mask);
3086
3087    ggml_tensor * penalized = gathered;
3088
3089    if (sctx->penalty_repeat != 1.0f) {
3090        ggml_tensor * pos_mask = ggml_step(ctx, penalized);
3091        ggml_tensor * neg_mask = ggml_sub(ctx, ggml_fill(ctx, pos_mask, 1.0f), pos_mask);
3092
3093        ggml_tensor * pos_scale = ggml_scale(ctx, pos_mask, 1.0f/sctx->penalty_repeat);
3094        ggml_tensor * neg_scale = ggml_scale(ctx, neg_mask, sctx->penalty_repeat);
3095        ggml_tensor * repeat_scale = ggml_add(ctx, pos_scale, neg_scale);
3096
3097        // scale inactive entries with 1 to avoid -INF * 0 = NaN for values masked by top-p
3098        repeat_scale = ggml_mul(ctx, repeat_scale, active_mask);
3099        repeat_scale = ggml_add(ctx, repeat_scale, inactive_mask);
3100        penalized = ggml_mul(ctx, gathered, repeat_scale);
3101    }
3102
3103    if (sctx->penalty_freq != 0.0f) {
3104        ggml_tensor * penalty_freq = ggml_scale(ctx, counts_f32, sctx->penalty_freq);
3105        penalized = ggml_sub(ctx, penalized, penalty_freq);
3106    }
3107
3108    if (sctx->penalty_present != 0.0f) {
3109        ggml_tensor * penalty_present = ggml_scale(ctx, active_mask, sctx->penalty_present);
3110        penalized = ggml_sub(ctx, penalized, penalty_present);
3111    }
3112
3113    if (sctx->has_candidates) {
3114        data->logits = penalized;
3115    } else {
3116        ggml_tensor * logits_rows = ggml_reshape_2d(ctx, logits, 1, ggml_nelements(logits));
3117        ggml_tensor * scatter_rows = ggml_reshape_2d(ctx, penalized, 1, sctx->n_max);
3118        logits_rows = ggml_set_rows(ctx, logits_rows, scatter_rows, sctx->inp_token_ids);
3119        data->logits = ggml_reshape_1d(ctx, logits_rows, ggml_nelements(logits));
3120    }
3121}
3122
3123static void llama_sampler_penalties_backend_set_input(struct llama_sampler * smpl) {
3124    auto * sctx = (llama_sampler_penalties *) smpl->ctx;
3125
3126    if (!sctx->inp_token_ids || !sctx->inp_counts || sctx->n_max <= 0 || sctx->n_vocab <= 0) {
3127        return;
3128    }
3129
3130    if (sctx->is_disabled()) {
3131        return;
3132    }
3133
3134    // fill active entries from the map
3135    int32_t n_active = 0;
3136
3137    for (const auto & it : sctx->token_count) {
3138        GGML_ASSERT(n_active < sctx->n_max);
3139        sctx->host_token_ids[n_active] = it.first;
3140        sctx->host_counts   [n_active] = it.second;
3141        ++n_active;
3142    }
3143
3144    // Sorting is required because backend_apply uses ggml_set_rows (a scatter-back operation)
3145    std::vector<std::pair<int32_t, int32_t>> entries;
3146    entries.reserve(n_active);
3147    for (int32_t i = 0; i < n_active; ++i) {
3148        entries.emplace_back(sctx->host_token_ids[i], sctx->host_counts[i]);
3149    }
3150    std::sort(entries.begin(), entries.end(), [](const auto & a, const auto & b) {
3151        return a.first < b.first;
3152    });
3153    for (int32_t i = 0; i < n_active; ++i) {
3154        sctx->host_token_ids[i] = entries[i].first;
3155        sctx->host_counts   [i] = entries[i].second;
3156    }
3157
3158    // Padding: Finds a filler token id that is not present in token_count.
3159    // Use it to do padding for the arrays, it avoids resizing every time.
3160    // The arrays must always have exactly n_max entries (the GPU tensor is a fixed size).
3161    int32_t filler = 0;
3162    if (n_active < sctx->n_max) {
3163        while (sctx->token_count.find(filler) != sctx->token_count.end()) {
3164            ++filler;
3165        }
3166        GGML_ASSERT(filler < sctx->n_vocab);
3167    }
3168
3169    // Fill the rest of the arrays with the filler token id and count 0.
3170    // Inactive slots are padded with a unique dummy token ID (count = 0).
3171    // The uniqueness matters because ggml_set_rows with duplicate indices can produce non-deterministic or incorrect results.
3172    // Using a filler token with count 0 that isn't in the active set is safe, because the active_mask step in backend_apply filters them out via ggml_step(counts_f32)
3173    for (int32_t i = n_active; i < sctx->n_max; ++i) {
3174        sctx->host_token_ids[i] = filler;
3175        sctx->host_counts   [i] = 0;
3176    }
3177
3178    ggml_backend_tensor_set(sctx->inp_token_ids, sctx->host_token_ids.data(), 0, sctx->n_max * sizeof(int32_t));
3179    ggml_backend_tensor_set(sctx->inp_counts,    sctx->host_counts.data(),    0, sctx->n_max * sizeof(int32_t));
3180}
3181
3182static void llama_sampler_penalties_backend_reset(struct llama_sampler * smpl) {
3183    auto * sctx = (llama_sampler_penalties *) smpl->ctx;
3184    sctx->inp_token_ids = nullptr;
3185    sctx->inp_counts    = nullptr;
3186}
3187
3188static struct llama_sampler_i llama_sampler_penalties_i = {
3189    /* .name              = */ llama_sampler_penalties_name,
3190    /* .accept            = */ llama_sampler_penalties_accept,
3191    /* .apply             = */ llama_sampler_penalties_apply,
3192    /* .reset             = */ llama_sampler_penalties_reset,
3193    /* .clone             = */ llama_sampler_penalties_clone,
3194    /* .free              = */ llama_sampler_penalties_free,
3195    /* .backend_init      = */ llama_sampler_penalties_backend_init,
3196    /* .backend_accept    = */ nullptr,
3197    /* .backend_apply     = */ llama_sampler_penalties_backend_apply,
3198    /* .backend_set_input = */ llama_sampler_penalties_backend_set_input,
3199    /* .backend_reset     = */ llama_sampler_penalties_backend_reset,
3200    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_penalties>,
3201};
3202
3203struct llama_sampler * llama_sampler_init_penalties(
3204        int32_t n_vocab,
3205        int32_t penalty_last_n,
3206        float penalty_repeat,
3207        float penalty_freq,
3208        float penalty_present) {
3209    penalty_last_n = std::max(penalty_last_n, 0);
3210
3211    if (llama_sampler_penalties::is_disabled(
3212                penalty_last_n, penalty_repeat, penalty_freq, penalty_present)) {
3213        return llama_sampler_init_empty("?penalties");
3214    }
3215
3216    return llama_sampler_init(
3217        /* .iface = */ &llama_sampler_penalties_i,
3218        /* .ctx   = */ new llama_sampler_penalties(
3219            n_vocab,
3220            penalty_last_n,
3221            penalty_repeat,
3222            penalty_freq,
3223            penalty_present)
3224    );
3225}
3226
3227// top-n-sigma
3228
3229struct llama_sampler_top_n_sigma {
3230    const float n;
3231};
3232
3233static const char * llama_sampler_top_n_sigma_name(const struct llama_sampler * /*smpl*/) {
3234    return "top-n-sigma";
3235}
3236
3237static void llama_sampler_top_n_sigma_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
3238    auto * ctx = (llama_sampler_top_n_sigma *) smpl->ctx;
3239
3240    if (ctx->n <= 0.0f || cur_p->size <= 1) {
3241        return;
3242    }
3243
3244    // find max logit and calculate mean
3245    float max = cur_p->data[0].logit;
3246    float logits_sum = 0;
3247    size_t valid_count = 0;
3248    for (size_t i = 0; i < cur_p->size; ++i) {
3249        // Only count non-negative infinity values
3250        if (cur_p->data[i].logit != -INFINITY) {
3251            max = std::max(max, cur_p->data[i].logit);
3252            logits_sum += cur_p->data[i].logit;
3253            valid_count++;
3254        }
3255    }
3256    float mean = valid_count > 0 ? logits_sum/valid_count : 0;
3257
3258    // calculate standard deviation
3259    float acc = 0;
3260    for (size_t i = 0; i < cur_p->size; ++i) {
3261        // Skip -infinity in std calculation
3262        if (cur_p->data[i].logit != -INFINITY) {
3263            acc += pow(cur_p->data[i].logit - mean, 2);
3264        }
3265    }
3266    float std = valid_count > 0 ? sqrt(acc/valid_count) : 0;
3267
3268    // apply mask
3269    for (size_t i = 0; i < cur_p->size; ++i) {
3270        if (cur_p->data[i].logit < max - (ctx->n * std)) {
3271            cur_p->data[i].logit = -INFINITY;
3272        }
3273    }
3274}
3275
3276static struct llama_sampler * llama_sampler_top_n_sigma_clone(const struct llama_sampler * smpl) {
3277    const auto * ctx = (const llama_sampler_top_n_sigma *) smpl->ctx;
3278    return llama_sampler_init_top_n_sigma(ctx->n);
3279}
3280
3281static void llama_sampler_top_n_sigma_free(struct llama_sampler * smpl) {
3282    delete (llama_sampler_top_n_sigma *) smpl->ctx;
3283}
3284
3285static struct llama_sampler_i llama_sampler_top_n_sigma_i = {
3286    /* .name              = */ llama_sampler_top_n_sigma_name,
3287    /* .accept            = */ nullptr,
3288    /* .apply             = */ llama_sampler_top_n_sigma_apply,
3289    /* .reset             = */ nullptr,
3290    /* .clone             = */ llama_sampler_top_n_sigma_clone,
3291    /* .free              = */ llama_sampler_top_n_sigma_free,
3292    /* .backend_init      = */ nullptr,
3293    /* .backend_accept    = */ nullptr,
3294    /* .backend_apply     = */ nullptr,
3295    /* .backend_set_input = */ nullptr,
3296    /* .backend_reset     = */ nullptr,
3297    /* .copy_state        = */ nullptr,
3298};
3299
3300struct llama_sampler * llama_sampler_init_top_n_sigma(float n) {
3301    const bool is_empty = (n <= 0.0f);
3302
3303    if (is_empty) {
3304        return llama_sampler_init_empty("?top-n-sigma");
3305    }
3306
3307    return llama_sampler_init(
3308        /* .iface = */ &llama_sampler_top_n_sigma_i,
3309        /* .ctx   = */ new llama_sampler_top_n_sigma {
3310            /* .n = */ n,
3311        }
3312    );
3313}
3314
3315// DRY
3316
3317struct llama_sampler_dry {
3318    const float   dry_multiplier;
3319    const float   dry_base;
3320    const int32_t dry_allowed_length;
3321    const int32_t dry_penalty_last_n;
3322
3323    std::unordered_multimap<llama_token, std::vector<llama_token>> dry_processed_breakers;
3324    std::vector<int> dry_repeat_count;
3325    std::unordered_map<llama_token, int> dry_max_token_repeat;
3326    ring_buffer<llama_token> last_tokens;
3327};
3328
3329// Ported from Koboldcpp, original PR: https://github.com/LostRuins/koboldcpp/pull/982 (Original author: pi6am)
3330static void get_overlapping_token_sequences(const llama_vocab & vocab, const std::string& str, std::unordered_multimap<llama_token, std::vector<llama_token>>& token_sequences, int max_tail_len = -1) {
3331    for (llama_token token_id = 0; token_id < (llama_token) vocab.n_tokens(); token_id++) {
3332        std::string word = vocab.detokenize({token_id}, true);
3333        if (word.find(str) != std::string::npos) {
3334            token_sequences.emplace(token_id, std::vector<llama_token>());
3335        } else {
3336            size_t word_len = word.size();
3337            size_t str_len = str.size();
3338            size_t pos = -1;
3339            while ((pos = word.find(str[0], pos + 1)) != std::string::npos) {
3340                bool match = true;
3341                size_t i;
3342                for (i = 1; i < str_len && i + pos < word_len; ++i) {
3343                    if (word[pos + i] != str[i]) {
3344                        match = false;
3345                        break;
3346                    }
3347                }
3348                if (match) {
3349                    std::vector<llama_token> tokenization = vocab.tokenize(str.substr(i), false, false);
3350                    if (max_tail_len >= 0 && tokenization.size() > (size_t)max_tail_len) {
3351                        tokenization.resize(max_tail_len);
3352                    }
3353
3354                    // Ensure we don't already have a duplicate matching tokenization
3355                    auto its = token_sequences.equal_range(token_id);
3356                    bool found = false;
3357                    for (auto it = its.first; it != its.second; ++it) {
3358                        if (tokenization == it->second) {
3359                            found = true;
3360                            break;
3361                        }
3362                    }
3363                    if (!found) {
3364                        token_sequences.emplace(token_id, tokenization);
3365                    }
3366                }
3367            }
3368        }
3369    }
3370}
3371
3372static const char * llama_sampler_dry_name(const struct llama_sampler * /*smpl*/) {
3373    return "dry";
3374}
3375
3376static void llama_sampler_dry_accept(struct llama_sampler * smpl, llama_token token) {
3377    auto * ctx = (llama_sampler_dry *) smpl->ctx;
3378    if (ctx->dry_multiplier == 0.0f || ctx->dry_base < 1.0f || ctx->dry_penalty_last_n == 0) {
3379        return;
3380    }
3381
3382    ctx->last_tokens.push_back(token);
3383}
3384
3385// Ported from Koboldcpp, original PR: https://github.com/LostRuins/koboldcpp/pull/982 (Original author: pi6am)
3386static void llama_sampler_dry_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
3387    auto * ctx = (llama_sampler_dry *) smpl->ctx;
3388
3389    if (ctx->dry_multiplier == 0.0f || ctx->dry_base < 1.0f || ctx->dry_penalty_last_n == 0) {
3390        return;
3391    }
3392
3393    int last_n_repeat = std::min((int) ctx->last_tokens.size(), ctx->dry_penalty_last_n);
3394
3395    if (last_n_repeat <= ctx->dry_allowed_length) {
3396        return;
3397    }
3398
3399    ctx->dry_repeat_count.assign(last_n_repeat, 0);
3400    ctx->dry_max_token_repeat.clear();
3401
3402    // Step 1: Look for restart sequences to limit the maximum repetition length.
3403    // Work backwards through the context looking for any token that begins a restart sequence.
3404    //
3405    // The collection `restart_sequences` is a mapping from a "head" token to all "tail"
3406    // sequences that together comprise a restart sequence. This allows us to quickly check
3407    // whether each token is the head of a complete sequence. Most restart sequences are actually
3408    // a single token, and for these the "tail" is an empty vector.
3409    //
3410    // If the token is a "head", test all restart sequences that begin with this token
3411    // (there will often only be one sequence for each token, but if sequences like 'aaaq1' and
3412    // 'aaa1' are used as restart strings, both could start with 'aaa' when tokenized). The
3413    // longest matching sequence (if any) is used to limit the maximum repetition length.
3414    //
3415    // Note that in the case case of a short sequence contained in a longer one, this might fail to
3416    // find the smallest value for `rep_limit`. For example, if 'amniotic' and 'ni' are both used as
3417    // restart sequences, 'ni' will be found first, and since it's shorter it will fail to suppress
3418    // 'otic'. This is a minor issue since fully contained restart sequences are likely to be rare.
3419    //
3420    // This is theoretically worst-case O(N^2) for arbitrary restart sequences, which is why we
3421    // have already clamped the maximum tail sequence length when generating `restart_sequences`.
3422    // With clamping, this scan is O(N) in the context length.
3423
3424    int rep_limit = last_n_repeat;
3425    for (int i = 0; i < last_n_repeat; ++i) {
3426        llama_token token = ctx->last_tokens.rat(i);
3427        auto its = ctx->dry_processed_breakers.equal_range(token);
3428        if (its.first == ctx->dry_processed_breakers.end()) {
3429            continue;
3430        }
3431        int longest_match = -1;
3432        for (auto it = its.first; it != its.second; ++it) {
3433            // Note that (*it) does not contain the head character, so seq_len will be
3434            // the restart sequence length minus 1.
3435            // In the common case of a single-token restart sequence, (*it) will be empty
3436            // and we will trivially match.
3437            int seq_len = (int)it->second.size();
3438            if (seq_len > longest_match && seq_len <= (int)i) {
3439                bool match = true;
3440                for (int offset = 0; offset < seq_len; ++offset) {
3441                    // The -1 when indexing `last_tokens` is because we already matched the head.
3442                    if (it->second[offset] != ctx->last_tokens.rat(i - offset - 1)) {
3443                        match = false;
3444                        break;
3445                    }
3446                }
3447                if (match) {
3448                    longest_match = seq_len;
3449                }
3450            }
3451        }
3452        if (longest_match >= 0) {
3453            // We found a restart sequence starting `i` tokens from the end and continuing for
3454            // `longest_match` tokens.
3455            rep_limit = i - longest_match;
3456            break;
3457        }
3458    }
3459    if (rep_limit < ctx->dry_allowed_length) {
3460        return;
3461    }
3462
3463    // Step 2: Iterate in reverse over the last N tokens of the context, using the "Z-algorithm" (in
3464    // the reverse direction) to efficiently compute the positions and lengths of suffixes appearing
3465    // elsewhere in the context. We limit the suffix length to `rep_limit` to respect restart sequences.
3466    //
3467    // This algorithm is not currently documented on Wikipedia, but there is a clear description here:
3468    // https://ivanyu.me/blog/2014/10/15/z-algorithm/
3469    //
3470    // The code below is adapted from the public domain implementation by the same author here:
3471    // https://github.com/ivanyu/string-algorithms/blob/master/z_algorithm.py
3472    //
3473    // Example:
3474    // Last N tokens: a b c c b c y a b c
3475    // Repeat counts: 0 0 3 1 0 2 0 0 0 0
3476    //                    ^
3477    //   This `3` means that the last three tokens of the context (a b c) also appear here.
3478    //
3479    // This step is worst case O(N) since the Z-algorithm is linear, despite the appearance of nested
3480    // for/while loops. This can be seen by observing that the `lt` and `rt` bounds are set after each
3481    // repeated suffix is detected (i.e. after each while loop when n > 0). These bound variables
3482    // ensure that the inner while loops only examine each token in the context once as the outer
3483    // for loop iterates over the context.
3484
3485    {
3486        const int last = last_n_repeat - 1;
3487
3488        int rt = 0;
3489        int lt = 0;
3490
3491        for (int k = 1; k < last_n_repeat; ++k) {
3492            if (k > rt) {
3493                // If k is outside the current Z-box, do naive computation.
3494                int n = 0;
3495                while (n + k < last_n_repeat && ctx->last_tokens.rat(n) == ctx->last_tokens.rat(n+k)) {
3496                    ++n;
3497                }
3498                ctx->dry_repeat_count[last - k] = std::min(n, rep_limit);
3499                if (n > 0) {
3500                    lt = k;
3501                    rt = k + n - 1;
3502                }
3503            } else {
3504                // If k is inside the current Z-box, consider two cases.
3505
3506                int p = k - lt; // Pair index.
3507                int right_part_len = rt - k + 1;
3508
3509                if (ctx->dry_repeat_count[last - p] < right_part_len) {
3510                    int n = std::min(ctx->dry_repeat_count[last - p], rep_limit);
3511                    ctx->dry_repeat_count[last - k] = n;
3512                } else {
3513                    int i = rt + 1;
3514                    while (i < last_n_repeat && ctx->last_tokens.rat(i) == ctx->last_tokens.rat(i - k)) {
3515                        i += 1;
3516                    }
3517
3518                    int n = std::min(i - k, rep_limit);
3519                    ctx->dry_repeat_count[last - k] = n;
3520                    lt = k;
3521                    rt = i - 1;
3522                }
3523            }
3524        }
3525    }
3526
3527    // Step 3: Iterate over dry_repeat_count and last_tokens, examining the maximum repeat length
3528    // that would be generated by emitting each new token that would extend a sequence.
3529    //
3530    // Following the same example as above:
3531    // Last N tokens: a b c c b c y a b c
3532    // Repeat counts: 0 0 3 1 0 2 0 0 0 0
3533    //
3534    // For each non-zero, look ahead one token. This token, if emitted, would extend the repetition.
3535    // c: 3 -> 4 (from `a b c` to `a b c c`)
3536    // b: 1 -> 2 (from `c` to `c b`)
3537    // y: 2 -> 3 (from `b c` to `b c y`)
3538
3539    for (int i = 0; i < last_n_repeat - 1; ++i) {
3540        int repeat_len = ctx->dry_repeat_count[i];
3541        if (repeat_len >= ctx->dry_allowed_length) {
3542            // This token ends a repeat, so the next token would continue one.
3543            // By convention, the value of `repeat_len` only includes the tokens currently
3544            // in the context, not the new token that would be added.
3545            llama_token token = ctx->last_tokens.rat(last_n_repeat - 2 - i);
3546            // Track the maximum sequence ending in this token.
3547            const auto& it = ctx->dry_max_token_repeat.find(token);
3548            if (it == ctx->dry_max_token_repeat.end() || it->second < repeat_len) {
3549                ctx->dry_max_token_repeat[token] = repeat_len;
3550            }
3551        }
3552    }
3553
3554    // Step 4: Apply logit penalties based on the maximum repeat length for relevant tokens.
3555
3556    // Prevent floating point overflow in `pow(penalty_base, exponent)` by clamping to `max_exponent`.
3557    // Compute it from `penalty_base` and the approximate log of `std::numeric_limits<float>::max()`
3558    const float FLOAT_MAX_LOG = 88.7228391f;
3559    int max_exponent = 0;
3560    if (ctx->dry_base > 1.000001f) {
3561        max_exponent = FLOAT_MAX_LOG / std::log(ctx->dry_base);
3562    }
3563
3564    for (size_t i = 0; i < cur_p->size; ++i) {
3565        const auto& af_kvp = ctx->dry_max_token_repeat.find(cur_p->data[i].id);
3566        if (af_kvp != ctx->dry_max_token_repeat.end()) {
3567            // Check all sequence breakers starting with this token
3568            auto range = ctx->dry_processed_breakers.equal_range(cur_p->data[i].id);
3569            bool is_single_token_breaker = false;
3570
3571            for (auto it = range.first; it != range.second; ++it) {
3572                if (it->second.empty()) {
3573                    is_single_token_breaker = true;
3574                    break;
3575                }
3576            }
3577
3578            // Apply penalty only if it's not a single-token sequence breaker
3579            if (!is_single_token_breaker) {
3580                int repeat_exp = af_kvp->second - ctx->dry_allowed_length;
3581                if (max_exponent > 0 && repeat_exp > max_exponent) {
3582                    repeat_exp = max_exponent;
3583                }
3584                float penalty = ctx->dry_multiplier * std::pow(ctx->dry_base, repeat_exp);
3585                cur_p->data[i].logit -= penalty;
3586            }
3587        }
3588    }
3589
3590    cur_p->sorted = false;
3591}
3592
3593static void llama_sampler_dry_reset(struct llama_sampler * smpl) {
3594    auto * ctx = (llama_sampler_dry *) smpl->ctx;
3595    ctx->last_tokens.clear();
3596    ctx->dry_repeat_count.clear();
3597    ctx->dry_max_token_repeat.clear();
3598}
3599
3600static struct llama_sampler * llama_sampler_dry_clone(const struct llama_sampler * smpl) {
3601    const auto * ctx = (llama_sampler_dry *) smpl->ctx;
3602
3603    llama_vocab dummy_vocab;
3604
3605    // dummy vocab is passed because it is only needed for raw sequence breaker processing, which we have already done and will simply be copying
3606    auto * result = llama_sampler_init_dry(&dummy_vocab, ctx->dry_multiplier, ctx->dry_base, ctx->dry_allowed_length, ctx->dry_penalty_last_n, NULL, 0);
3607
3608    // Copy the state, including the processed breakers
3609    {
3610        auto * result_ctx = (llama_sampler_dry *) result->ctx;
3611        result_ctx->dry_processed_breakers = ctx->dry_processed_breakers;
3612        result_ctx->dry_repeat_count = ctx->dry_repeat_count;
3613        result_ctx->dry_max_token_repeat = ctx->dry_max_token_repeat;
3614        result_ctx->last_tokens = ctx->last_tokens;
3615    }
3616
3617    return result;
3618}
3619
3620static void llama_sampler_dry_free(struct llama_sampler * smpl) {
3621    delete (llama_sampler_dry *) smpl->ctx;
3622}
3623
3624static struct llama_sampler_i llama_sampler_dry_i = {
3625    /* .name              = */ llama_sampler_dry_name,
3626    /* .accept            = */ llama_sampler_dry_accept,
3627    /* .apply             = */ llama_sampler_dry_apply,
3628    /* .reset             = */ llama_sampler_dry_reset,
3629    /* .clone             = */ llama_sampler_dry_clone,
3630    /* .free              = */ llama_sampler_dry_free,
3631    /* .backend_init      = */ nullptr,
3632    /* .backend_accept    = */ nullptr,
3633    /* .backend_apply     = */ nullptr,
3634    /* .backend_set_input = */ nullptr,
3635    /* .backend_reset     = */ nullptr,
3636    /* .copy_state        = */ nullptr,
3637};
3638
3639struct llama_sampler * llama_sampler_init_dry(const struct llama_vocab * vocab, float dry_multiplier, float dry_base, int32_t dry_allowed_length, int32_t dry_penalty_last_n, const char** seq_breakers, size_t num_breakers) {
3640    dry_penalty_last_n = std::max(dry_penalty_last_n, 0);
3641    std::unordered_multimap<llama_token, std::vector<llama_token>> processed_breakers;
3642    const int MAX_CHAR_LEN = 40;
3643    const int MAX_SEQ_LEN = 20;
3644
3645    const bool dry_enabled = (dry_multiplier != 0.0f && dry_base >= 1.0f && dry_penalty_last_n != 0);
3646
3647    if (!dry_enabled) {
3648        return llama_sampler_init_empty("?dry");
3649    }
3650
3651    if (dry_enabled && seq_breakers != nullptr && num_breakers > 0) {
3652        // Process sequence breakers
3653        for (size_t i = 0; i < num_breakers; ++i) {
3654            if (seq_breakers[i] == nullptr || std::strlen(seq_breakers[i]) == 0) {
3655                LLAMA_LOG_WARN("skipping null or empty DRY sequence breaker at index %zu\n", i);
3656                continue;
3657            }
3658
3659            std::string sequence_break(seq_breakers[i]);
3660            if (sequence_break.empty()) {
3661                LLAMA_LOG_WARN("skipping empty DRY sequence breaker\n");
3662                continue;
3663            }
3664
3665            if (sequence_break.size() > MAX_CHAR_LEN) {
3666                LLAMA_LOG_WARN("truncating DRY sequence breaker to %d characters\n", MAX_CHAR_LEN);
3667                sequence_break.resize(MAX_CHAR_LEN);
3668            }
3669
3670            get_overlapping_token_sequences(*vocab, sequence_break, processed_breakers, MAX_SEQ_LEN);
3671        }
3672    }
3673
3674    return llama_sampler_init(
3675        /* .iface = */ &llama_sampler_dry_i,
3676        /* .ctx   = */ new llama_sampler_dry {
3677            /* .dry_multiplier         = */ dry_multiplier,
3678            /* .dry_base               = */ dry_base,
3679            /* .dry_allowed_length     = */ dry_allowed_length,
3680            /* .dry_penalty_last_n     = */ dry_penalty_last_n,
3681            /* .dry_processed_breakers = */ std::move(processed_breakers),
3682            /* .dry_repeat_count       = */ dry_enabled ? std::vector<int>(dry_penalty_last_n, 0) : std::vector<int>{},
3683            /* .dry_max_token_repeat   = */ {},
3684            /* .last_tokens            = */ dry_enabled ? ring_buffer<llama_token>(dry_penalty_last_n) : ring_buffer<llama_token>(0),
3685        }
3686    );
3687}
3688
3689// wrapper for test-sampling.cpp
3690struct llama_sampler * llama_sampler_init_dry_testing(float dry_multiplier, float dry_base, int32_t dry_allowed_length, int32_t dry_penalty_last_n, const std::vector<std::vector<llama_token>>& seq_breakers) {
3691    llama_vocab dummy_vocab;
3692    auto * result = llama_sampler_init_dry(&dummy_vocab, dry_multiplier, dry_base, dry_allowed_length, dry_penalty_last_n, NULL, 0);
3693    auto * ctx = (llama_sampler_dry *) result->ctx;
3694
3695    // Process the token-based sequence breakers
3696    ctx->dry_processed_breakers.clear();
3697    if (seq_breakers.empty()) {
3698        LLAMA_LOG_WARN("empty DRY sequence breakers list in llama_sampler_init_dry_testing\n");
3699    } else {
3700        for (const auto& breaker : seq_breakers) {
3701            if (breaker.empty()) {
3702                LLAMA_LOG_WARN("skipping DRY empty sequence breaker\n");
3703                continue;
3704            }
3705            llama_token head_token = breaker[0];
3706            std::vector<llama_token> tail_tokens(breaker.begin() + 1, breaker.end());
3707            ctx->dry_processed_breakers.emplace(head_token, std::move(tail_tokens));
3708        }
3709
3710        if (ctx->dry_processed_breakers.empty()) {
3711            LLAMA_LOG_WARN("no valid DRY sequence breakers processed in llama_sampler_init_dry_testing\n");
3712        }
3713    }
3714
3715    return result;
3716}
3717
3718// adaptive-p sampler state
3719//
3720// maintains an exponential moving average of the *ORIGINAL* probabilities
3721// of selected tokens, used to compute an adapted target at each sampling step.
3722//
3723// see llama.h for a full description of the sampler
3724//
3725// ref: https://github.com/ggml-org/llama.cpp/pull/17927
3726//
3727struct llama_sampler_adaptive_p {
3728    const float        target;            // target probability (0.0 - 1.0; negative = disabled)
3729    const float        decay;             // EMA decay; history ~= 1/(1-decay) tokens (0.0 - 0.99)
3730    const uint32_t     seed;              // original RNG seed
3731    uint32_t           seed_cur;          // actual RNG seed
3732    std::mt19937       rng;               // RNG state
3733    float              weighted_sum;      // sum(p_i * decay^i)
3734    float              total_weight;      // sum(decay^i), converges to 1/(1-decay)
3735    std::vector<float> original_probs;    // pre-transform probs, cached for EMA update
3736    llama_token        pending_token_id;  // token ID of selected token
3737    int32_t            pending_token_idx; // index of orig. prob. of selected token in original_probs
3738};
3739
3740// adaptive probability transformation constants
3741static constexpr float DISTRIBUTION_WIDTH =  0.3f;
3742static constexpr float PEAK_LOGIT_VALUE   =  5.0f;
3743static constexpr float SHARPNESS          = 10.0f;
3744static constexpr float INV_WIDTH          =  1.0f / DISTRIBUTION_WIDTH;
3745
3746static const char * llama_sampler_adaptive_p_name(const struct llama_sampler * /*smpl*/) {
3747    return "adaptive-p";
3748}
3749
3750static void llama_sampler_adaptive_p_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
3751    auto * ctx = (llama_sampler_adaptive_p *) smpl->ctx;
3752
3753    llama_sampler_softmax_impl(cur_p, false);
3754
3755    if (ctx->target < 0.0f) {
3756        // at negative target values, adaptive-p is no-op
3757        // we simply sample from the existing distribution
3758        cur_p->selected = llama_sample_dist(cur_p, ctx->rng);
3759        return;
3760    }
3761
3762    // store the original probabilities
3763    ctx->original_probs.resize(cur_p->size);
3764    for (size_t i = 0; i < cur_p->size; ++i) {
3765        ctx->original_probs[i] = cur_p->data[i].p;
3766    }
3767
3768    // using the EMA, compute the adapted target probability for the current sampling step
3769    auto target = std::clamp(ctx->target, 0.0f, 1.0f);
3770    float adapted_target = std::clamp(
3771        ctx->total_weight == 0.0f ? target : 2.0f * target - (ctx->weighted_sum / ctx->total_weight),
3772        0.0f, 1.0f
3773    );
3774
3775    // adaptive probability transform
3776    //
3777    // quadratic near target for fine differentiation, transitioning to linear decay in the
3778    // tails. unbounded negative logits ensure proper suppression of far-from-target tokens
3779    // after the softmax.
3780    //
3781    for (size_t i = 0; i < cur_p->size; ++i) {
3782        if (cur_p->data[i].logit == -INFINITY) {
3783            // don't transform logits that are -INFINITY
3784            // (as masked out by e.g. min-p and top-p when using backend sampling)
3785            continue;
3786        }
3787        float dist = std::abs((cur_p->data[i].p - adapted_target) * INV_WIDTH);
3788        cur_p->data[i].logit = PEAK_LOGIT_VALUE - SHARPNESS * dist * dist / (1.0f + dist);
3789    }
3790
3791    // softmax and sample from the transformed distribution
3792    llama_sampler_softmax_impl(cur_p, false);
3793    const int idx   = llama_sample_dist(cur_p, ctx->rng);
3794    cur_p->selected = idx;
3795
3796    // store the selected token ID for acceptance later
3797    ctx->pending_token_id  = cur_p->data[idx].id;
3798    ctx->pending_token_idx = idx;
3799}
3800
3801static void llama_sampler_adaptive_p_accept(struct llama_sampler * smpl, llama_token token) {
3802    auto * ctx = (llama_sampler_adaptive_p *) smpl->ctx;
3803    if (ctx->pending_token_id == token) {
3804        GGML_ASSERT(ctx->pending_token_id != LLAMA_TOKEN_NULL);
3805        GGML_ASSERT(ctx->pending_token_idx != -1);
3806        // update EMA with the original probability of the selected token
3807        ctx->weighted_sum = ctx->original_probs[ctx->pending_token_idx] + ctx->decay * ctx->weighted_sum;
3808        ctx->total_weight = 1.0f + ctx->decay * ctx->total_weight;
3809    }
3810    ctx->pending_token_id = LLAMA_TOKEN_NULL;
3811    ctx->pending_token_idx = -1;
3812}
3813
3814static void llama_sampler_adaptive_p_reset(struct llama_sampler * smpl) {
3815    auto * ctx = (llama_sampler_adaptive_p *) smpl->ctx;
3816    // ctx->target and ctx->decay never change after init, so it's safe to keep them as is.
3817    // original_probs is completely overwritten on every call to _apply.
3818    // so we only need to reset the EMA state and pending token.
3819    ctx->weighted_sum      = ctx->target / (1.0f - ctx->decay);
3820    ctx->total_weight      = 1.0f / (1.0f - ctx->decay);
3821    ctx->pending_token_id  = LLAMA_TOKEN_NULL;
3822    ctx->pending_token_idx = -1;
3823    ctx->seed_cur          = get_rng_seed(ctx->seed);
3824    ctx->rng.seed(ctx->seed_cur);
3825}
3826
3827static struct llama_sampler * llama_sampler_adaptive_p_clone(const struct llama_sampler * smpl) {
3828    const auto * ctx  = (const llama_sampler_adaptive_p *) smpl->ctx;
3829    auto * result     = llama_sampler_init_adaptive_p(ctx->target, ctx->decay, ctx->seed);
3830    auto * result_ctx = (llama_sampler_adaptive_p *) result->ctx;
3831
3832    // copy everything (target, decay, seed, and RNG are already set)
3833    result_ctx->weighted_sum      = ctx->weighted_sum;
3834    result_ctx->total_weight      = ctx->total_weight;
3835    result_ctx->pending_token_id  = ctx->pending_token_id;
3836    result_ctx->pending_token_idx = ctx->pending_token_idx;
3837
3838    return result;
3839}
3840
3841static void llama_sampler_adaptive_p_free(struct llama_sampler * smpl) {
3842    delete (llama_sampler_adaptive_p *) smpl->ctx;
3843}
3844
3845static struct llama_sampler_i llama_sampler_adaptive_p_i = {
3846    /* .name              = */ llama_sampler_adaptive_p_name,
3847    /* .accept            = */ llama_sampler_adaptive_p_accept,
3848    /* .apply             = */ llama_sampler_adaptive_p_apply,
3849    /* .reset             = */ llama_sampler_adaptive_p_reset,
3850    /* .clone             = */ llama_sampler_adaptive_p_clone,
3851    /* .free              = */ llama_sampler_adaptive_p_free,
3852    /* .backend_init      = */ nullptr,
3853    /* .backend_accept    = */ nullptr,
3854    /* .backend_apply     = */ nullptr,
3855    /* .backend_set_input = */ nullptr,
3856    /* .backend_reset     = */ nullptr,
3857    /* .copy_state        = */ nullptr,
3858};
3859
3860struct llama_sampler * llama_sampler_init_adaptive_p(
3861    float    target,
3862    float    decay,
3863    uint32_t seed
3864) {
3865    auto seed_cur = get_rng_seed(seed);
3866    float clamped_decay = std::clamp(decay, 0.0f, 0.99f);
3867    return llama_sampler_init(
3868        /* .iface = */ &llama_sampler_adaptive_p_i,
3869        /* .ctx   = */ new llama_sampler_adaptive_p {
3870            /* .target            = */ target,
3871            /* .decay             = */ clamped_decay,
3872            /* .seed              = */ seed,
3873            /* .seed_cur          = */ seed_cur,
3874            /* .rng               = */ std::mt19937(seed_cur),
3875            /* .weighted_sum      = */ target / (1.0f - clamped_decay),
3876            /* .total_weight      = */ 1.0f / (1.0f - clamped_decay),
3877            /* .original_probs    = */ {},
3878            /* .pending_token_id  = */ LLAMA_TOKEN_NULL,
3879            /* .pending_token_idx = */ -1
3880        }
3881    );
3882}
3883
3884// logit-bias
3885
3886struct llama_sampler_logit_bias : public llama_sampler_backend {
3887    const int32_t n_vocab;
3888
3889    const std::vector<llama_logit_bias> logit_bias;
3890
3891    std::vector<llama_logit_bias> to_search;
3892
3893    struct ggml_tensor * inp_logit_bias;
3894    struct ggml_tensor * inp_logit_idxs;
3895};
3896
3897static const char * llama_sampler_logit_bias_name(const struct llama_sampler * smpl) {
3898    auto * ctx = (llama_sampler_logit_bias *) smpl->ctx;
3899    return ctx->get_name();
3900}
3901
3902static void llama_sampler_logit_bias_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
3903    auto * ctx = (llama_sampler_logit_bias *) smpl->ctx;
3904
3905    if (ctx->logit_bias.empty()) {
3906        return;
3907    }
3908
3909    ctx->to_search.clear();
3910
3911    // update the candidates that have not been shuffled in the vocabulary (i.e. idx == id)
3912    for (const auto & lb : ctx->logit_bias) {
3913        if (lb.token >= 0 && cur_p->size > (size_t) lb.token && cur_p->data[lb.token].id == lb.token) {
3914            cur_p->data[lb.token].logit += lb.bias;
3915        } else {
3916            ctx->to_search.push_back(lb);
3917        }
3918    }
3919
3920    if (ctx->to_search.empty()) {
3921        return;
3922    }
3923
3924    // search for the remaining candidates that were not found in the previous step
3925    for (size_t i = 0; i < cur_p->size; ++i) {
3926        for (const auto & lb : ctx->to_search) {
3927            if (cur_p->data[i].id == lb.token) {
3928                cur_p->data[i].logit += lb.bias;
3929                break;
3930            }
3931        }
3932    }
3933}
3934
3935static struct llama_sampler * llama_sampler_logit_bias_clone(const struct llama_sampler * smpl) {
3936    const auto * ctx = (const llama_sampler_logit_bias *) smpl->ctx;
3937    return llama_sampler_init_logit_bias(ctx->n_vocab, ctx->logit_bias.size(), ctx->logit_bias.data());
3938}
3939
3940static void llama_sampler_logit_bias_free(struct llama_sampler * smpl) {
3941    delete (llama_sampler_logit_bias *) smpl->ctx;
3942}
3943
3944static void llama_sampler_logit_bias_backend_apply(
3945        struct llama_sampler      * smpl,
3946        struct ggml_context       * ctx,
3947        struct ggml_cgraph        * gf,
3948        struct llama_sampler_data * data) {
3949    GGML_UNUSED(gf);
3950    GGML_UNUSED(ctx);
3951
3952    auto * sctx = (llama_sampler_logit_bias *) smpl->ctx;
3953    if (sctx->logit_bias.empty()) {
3954        return;
3955    }
3956
3957    const size_t n = sctx->logit_bias.size();
3958
3959    if (sctx->inp_logit_bias == nullptr) {
3960        GGML_ASSERT(sctx->inp_logit_idxs == nullptr);
3961
3962        sctx->inp_logit_bias = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 1, n);
3963        ggml_set_name(sctx->inp_logit_bias, "logit_bias");
3964        ggml_set_input(sctx->inp_logit_bias);
3965
3966        sctx->inp_logit_idxs = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, n);
3967        ggml_set_name(sctx->inp_logit_idxs, "logit_idxs");
3968        ggml_set_input(sctx->inp_logit_idxs);
3969    }
3970
3971    ggml_tensor * cur = ggml_fill(ctx, data->logits, 0.0f);
3972
3973    cur = ggml_reshape_2d(ctx, cur, 1, ggml_nelements(cur));
3974    cur = ggml_set_rows(ctx, cur, sctx->inp_logit_bias, sctx->inp_logit_idxs);
3975    cur = ggml_reshape_1d(ctx, cur, ggml_nelements(cur));
3976
3977    data->logits = ggml_add(ctx, data->logits, cur);
3978}
3979
3980static void llama_sampler_logit_bias_backend_set_input(struct llama_sampler * smpl) {
3981    auto * sctx = (llama_sampler_logit_bias *) smpl->ctx;
3982    if (sctx->logit_bias.empty()) {
3983        return;
3984    }
3985
3986    GGML_ASSERT(sctx->inp_logit_bias != nullptr);
3987    GGML_ASSERT(sctx->inp_logit_idxs != nullptr);
3988
3989    const size_t n = sctx->logit_bias.size();
3990
3991    std::vector<float>   data_logit_bias(n, 0.0f);
3992    std::vector<int32_t> data_logit_idxs(n, 0);
3993    for (size_t i = 0; i < n; ++i) {
3994        const auto & lb = sctx->logit_bias[i];
3995        GGML_ASSERT(lb.token >= 0 && lb.token < (int32_t) sctx->n_vocab);
3996        data_logit_bias[i] = lb.bias;
3997        data_logit_idxs[i] = lb.token;
3998    }
3999
4000    ggml_backend_tensor_set(sctx->inp_logit_bias, data_logit_bias.data(), 0, ggml_nbytes(sctx->inp_logit_bias));
4001    ggml_backend_tensor_set(sctx->inp_logit_idxs, data_logit_idxs.data(), 0, ggml_nbytes(sctx->inp_logit_idxs));
4002}
4003
4004static void llama_sampler_logit_bias_backend_reset(struct llama_sampler * smpl) {
4005    auto * sctx = (llama_sampler_logit_bias *) smpl->ctx;
4006    sctx->inp_logit_bias = nullptr;
4007    sctx->inp_logit_idxs = nullptr;
4008}
4009
4010static bool llama_sampler_logit_bias_backend_init(
4011        struct llama_sampler       * smpl,
4012        ggml_backend_buffer_type_t   buft,
4013        uint32_t                     n_outputs_max_per_seq) {
4014    GGML_UNUSED(buft);
4015    GGML_UNUSED(n_outputs_max_per_seq);
4016
4017    auto * sctx = (llama_sampler_logit_bias *) smpl->ctx;
4018
4019    sctx->init(true);
4020
4021    if (sctx->logit_bias.empty()) {
4022        return true;
4023    }
4024
4025    return true;
4026}
4027
4028static struct llama_sampler_i llama_sampler_logit_bias_i = {
4029    /* .name              = */ llama_sampler_logit_bias_name,
4030    /* .accept            = */ nullptr,
4031    /* .apply             = */ llama_sampler_logit_bias_apply,
4032    /* .reset             = */ nullptr,
4033    /* .clone             = */ llama_sampler_logit_bias_clone,
4034    /* .free              = */ llama_sampler_logit_bias_free,
4035    /* .backend_init      = */ llama_sampler_logit_bias_backend_init,
4036    /* .backend_accept    = */ nullptr,
4037    /* .backend_apply     = */ llama_sampler_logit_bias_backend_apply,
4038    /* .backend_set_input = */ llama_sampler_logit_bias_backend_set_input,
4039    /* .backend_reset     = */ llama_sampler_logit_bias_backend_reset,
4040    /* .copy_state        = */ llama_sampler_backend_copy_state<llama_sampler_logit_bias>,
4041};
4042
4043struct llama_sampler * llama_sampler_init_logit_bias(
4044                         int32_t   n_vocab,
4045                         int32_t   n_logit_bias,
4046          const llama_logit_bias * logit_bias) {
4047    const bool is_empty = n_logit_bias <= 0;
4048
4049    if (is_empty) {
4050        return llama_sampler_init_empty("?logit-bias");
4051    }
4052
4053    return llama_sampler_init(
4054        /* .iface = */ &llama_sampler_logit_bias_i,
4055        /* .ctx   = */ new llama_sampler_logit_bias {
4056            ("logit-bias"),
4057            /* .n_vocab        = */ n_vocab,
4058            /* .logit_bias     = */ std::vector<llama_logit_bias>(logit_bias, logit_bias + n_logit_bias),
4059            /* .to_search      = */ {},
4060            /* .inp_logit_bias = */ nullptr,
4061            /* .inp_logit_idxs = */ nullptr,
4062        }
4063    );
4064}
4065
4066// infill
4067
4068//#define GGML_DEBUG_SAMPLER_INFILL
4069
4070struct llama_sampler_infill {
4071    const struct llama_vocab * vocab;
4072
4073    std::vector<char> buf0;
4074    std::vector<char> buf1;
4075};
4076
4077static const char * llama_sampler_infill_name(const struct llama_sampler * /*smpl*/) {
4078    return "infill";
4079}
4080
4081static void llama_sampler_infill_apply(struct llama_sampler * smpl, llama_token_data_array * cur_p) {
4082    auto * ctx = (llama_sampler_infill *) smpl->ctx;
4083
4084    llama_sampler_softmax_impl(cur_p, true);
4085
4086#if defined(GGML_DEBUG_SAMPLER_INFILL)
4087#define LOG_DBG_CUR LLAMA_LOG_DEBUG
4088#else
4089#define LOG_DBG_CUR(...)
4090#endif
4091
4092    for (size_t i = 0; i < cur_p->size; ++i) {
4093        LOG_DBG_CUR("%s: cur_p[%3zu] = { id: %6d, p: %.6f, logit: %6.3f }\n", __func__, i, cur_p->data[i].id, cur_p->data[i].p, cur_p->data[i].logit);
4094    }
4095
4096    float p_txt_sum = 0.0f;
4097    float p_eog_sum = 0.0f;
4098
4099    for (size_t i = 0; i < cur_p->size; ++i) {
4100        if (ctx->vocab->is_eog(cur_p->data[i].id)) {
4101            p_eog_sum += cur_p->data[i].p;
4102        } else {
4103            p_txt_sum += cur_p->data[i].p;
4104        }
4105    }
4106
4107    const float rat = p_eog_sum == 0.0 ? INFINITY : p_txt_sum / p_eog_sum; GGML_UNUSED(rat);
4108
4109    LOG_DBG_CUR("%s: p_txt_sum = %.2f, p_eog_sum = %.2f, rat = %.2f, n = %zu\n", __func__, p_txt_sum, p_eog_sum, rat, cur_p->size);
4110
4111    if (3*p_eog_sum*cur_p->size > p_txt_sum) {
4112        LOG_DBG_CUR("%s: the ratio p_txt/p_eog = %.2f is too low -> sampling EOG\n", __func__, p_txt_sum/p_eog_sum);
4113
4114        // keep just the EOG tokens
4115        const auto size_org = cur_p->size;
4116
4117        cur_p->size = 0;
4118
4119        float p_sum = 0.0f;
4120
4121        for (size_t i = 0; i < size_org; ++i) {
4122            if (ctx->vocab->is_eog(cur_p->data[i].id)) {
4123                p_sum += cur_p->data[i].p;
4124
4125                cur_p->data[cur_p->size++] = cur_p->data[i];
4126            }
4127        }
4128
4129        // normalize probs
4130        for (size_t i = 0; i < cur_p->size; ++i) {
4131            cur_p->data[i].p /= p_sum;
4132        }
4133
4134        return;
4135    }
4136
4137    size_t n_combined = 0; GGML_UNUSED(n_combined);
4138
4139    // combine tokens with common prefix
4140    for (size_t i0 = 0; i0 < cur_p->size; ++i0) {
4141        for (size_t i1 = 0; i1 < cur_p->size; ++i1) {
4142            if (cur_p->data[i0].logit == -INFINITY) {
4143                break;
4144            }
4145
4146            if (i0 == i1 || cur_p->data[i1].logit == -INFINITY) {
4147                continue;
4148            }
4149
4150            int len0 = ctx->vocab->token_to_piece(cur_p->data[i0].id, ctx->buf0.data(), ctx->buf0.size(), 0, false);
4151            if (len0 < 0) {
4152                ctx->buf0.resize(len0);
4153                len0 = ctx->vocab->token_to_piece(cur_p->data[i0].id, ctx->buf0.data(), ctx->buf0.size(), 0, false);
4154                assert(len0 > 0);
4155            }
4156
4157            int len1 = ctx->vocab->token_to_piece(cur_p->data[i1].id, ctx->buf1.data(), ctx->buf1.size(), 0, false);
4158            if (len1 < 0) {
4159                ctx->buf1.resize(len1);
4160                len1 = ctx->vocab->token_to_piece(cur_p->data[i1].id, ctx->buf1.data(), ctx->buf1.size(), 0, false);
4161                assert(len1 > 0);
4162            }
4163
4164            // token i0 is a prefix of token i1
4165            if (len0 > 0 && len0 <= len1 && memcmp(ctx->buf0.data(), ctx->buf1.data(), len0) == 0) {
4166                int dst = i0;
4167                int src = i1;
4168
4169                // merge into the token with higher probability
4170                if (cur_p->data[i1].p > cur_p->data[i0].p) {
4171                    std::swap(dst, src);
4172                }
4173
4174                cur_p->data[dst].p += cur_p->data[src].p;
4175                cur_p->data[src].logit = -INFINITY;
4176                cur_p->data[src].p     = 0.0f;
4177
4178                n_combined++;
4179            }
4180        }
4181    }
4182
4183    size_t n_non_eog = 0;
4184
4185    size_t size_org = cur_p->size;
4186
4187    float p_sum = 0.0f;
4188    float thold = 0.2f;
4189
4190    cur_p->size = 0;
4191
4192    LOG_DBG_CUR("%s: n_combined = %zu, applying thold = %.3f\n", __func__, n_combined, thold);
4193
4194    for (size_t i = 0; i < size_org; ++i) {
4195        const bool is_eog = ctx->vocab->is_eog(cur_p->data[i].id);
4196
4197        if (cur_p->data[i].p < thold && !is_eog) {
4198            continue;
4199        }
4200
4201        if (!is_eog) {
4202            ++n_non_eog;
4203        }
4204
4205        p_sum += cur_p->data[i].p;
4206
4207        // keep this token
4208        cur_p->data[cur_p->size++] = cur_p->data[i];
4209    }
4210
4211    LOG_DBG_CUR("%s: n_non_eog = %zu\n", __func__, n_non_eog);
4212
4213    // if no non-EOG tokens are left -> reduce cur_p to single EOT token
4214    if (n_non_eog == 0) {
4215        cur_p->size = 1;
4216        cur_p->data[0].id = ctx->vocab->token_eot();
4217        if (cur_p->data[0].id == LLAMA_TOKEN_NULL) {
4218            cur_p->data[0].id = ctx->vocab->token_eos();
4219        }
4220        cur_p->data[0].logit = 1.0f;
4221
4222        GGML_ASSERT(cur_p->data[0].id != LLAMA_TOKEN_NULL);
4223
4224        return;
4225    }
4226
4227    // normalize probs
4228    for (size_t i = 0; i < cur_p->size; ++i) {
4229        cur_p->data[i].p /= p_sum;
4230
4231        LOG_DBG_CUR("%s: cur_p[%3zu] = { id: %6d, p: %.6f, logit: %6.3f }\n", __func__, i, cur_p->data[i].id, cur_p->data[i].p, cur_p->data[i].logit);
4232    }
4233
4234    size_org = cur_p->size;
4235    p_sum = 0.0f;
4236    thold = 1.0/(n_non_eog + 1);
4237
4238    cur_p->size = 0;
4239
4240    LOG_DBG_CUR("%s: applying thold = %.3f\n", __func__, thold);
4241
4242    for (size_t i = 0; i < size_org; ++i) {
4243        const bool is_eog = ctx->vocab->is_eog(cur_p->data[i].id);
4244
4245        if (cur_p->data[i].p < thold && !is_eog) {
4246            continue;
4247        }
4248
4249        p_sum += cur_p->data[i].p;
4250
4251        cur_p->data[cur_p->size++] = cur_p->data[i];
4252    }
4253
4254    // normalize probs
4255    for (size_t i = 0; i < cur_p->size; ++i) {
4256        cur_p->data[i].p /= p_sum;
4257
4258        LOG_DBG_CUR("%s: cur_p[%3zu] = { id: %6d, p: %.6f, logit: %6.3f }\n", __func__, i, cur_p->data[i].id, cur_p->data[i].p, cur_p->data[i].logit);
4259    }
4260
4261#undef LOG_DBG_CUR
4262}
4263
4264static struct llama_sampler * llama_sampler_infill_clone(const struct llama_sampler * smpl) {
4265    const auto * ctx = (const llama_sampler_infill *) smpl->ctx;
4266    return llama_sampler_init_infill(ctx->vocab);
4267}
4268
4269static void llama_sampler_infill_free(struct llama_sampler * smpl) {
4270    delete (llama_sampler_infill *) smpl->ctx;
4271}
4272
4273static struct llama_sampler_i llama_sampler_infill_i = {
4274    /* .name              = */ llama_sampler_infill_name,
4275    /* .accept            = */ nullptr,
4276    /* .apply             = */ llama_sampler_infill_apply,
4277    /* .reset             = */ nullptr,
4278    /* .clone             = */ llama_sampler_infill_clone,
4279    /* .free              = */ llama_sampler_infill_free,
4280    /* .backend_init      = */ nullptr,
4281    /* .backend_accept    = */ nullptr,
4282    /* .backend_apply     = */ nullptr,
4283    /* .backend_set_input = */ nullptr,
4284    /* .backend_reset     = */ nullptr,
4285    /* .copy_state        = */ nullptr,
4286};
4287
4288struct llama_sampler * llama_sampler_init_infill(const struct llama_vocab * vocab) {
4289    return llama_sampler_init(
4290        /* .iface = */ &llama_sampler_infill_i,
4291        /* .ctx   = */ new llama_sampler_infill {
4292            /* .vocab = */ vocab,
4293            /* .buf0  = */ std::vector<char>(512),
4294            /* .buf1  = */ std::vector<char>(512),
4295        }
4296    );
4297}
4298
4299void llama_sampler_copy(const struct llama_sampler * src, struct llama_sampler * dst) {
4300    if (!src || !dst || src == dst) {
4301        return;
4302    }
4303
4304    GGML_ASSERT(src->iface == dst->iface && "llama_sampler_copy: cannot copy between different sampler types");
4305
4306    if (dst->iface->copy_state) {
4307        dst->iface->copy_state(src, dst);
4308        return;
4309    }
4310
4311    // build a temporary sampler carrying src's current state
4312    llama_sampler * tmp = llama_sampler_clone(src);
4313
4314    // free dst's old state (frees dst->ctx, including children for a chain)
4315    if (dst->iface->free) {
4316        dst->iface->free(dst);
4317    }
4318
4319    // transplant tmp's state into dst, then destroy the (now empty) temp shell
4320    dst->ctx = tmp->ctx;
4321    tmp->ctx = nullptr;
4322    delete tmp;
4323}
4324
4325// utils
4326
4327uint32_t llama_sampler_get_seed(const struct llama_sampler * smpl) {
4328    if (smpl->iface == &llama_sampler_dist_i) {
4329        return ((const llama_sampler_dist *) smpl->ctx)->seed_cur;
4330    }
4331
4332    if (smpl->iface == &llama_sampler_mirostat_i) {
4333        return ((const llama_sampler_mirostat *) smpl->ctx)->seed_cur;
4334    }
4335
4336    if (smpl->iface == &llama_sampler_mirostat_v2_i) {
4337        return ((const llama_sampler_mirostat_v2 *) smpl->ctx)->seed_cur;
4338    }
4339
4340    if (smpl->iface == &llama_sampler_chain_i) {
4341        const auto * ctx = (const llama_sampler_chain *) smpl->ctx;
4342        for (auto it = ctx->samplers.rbegin(); it != ctx->samplers.rend(); ++it) {
4343            const uint32_t seed = llama_sampler_get_seed(it->ptr);
4344            if (seed != LLAMA_DEFAULT_SEED) {
4345                return seed;
4346            }
4347        }
4348    }
4349
4350    return LLAMA_DEFAULT_SEED;
4351}
4352
4353// perf
4354
4355struct llama_perf_sampler_data llama_perf_sampler(const struct llama_sampler * chain) {
4356    struct llama_perf_sampler_data data = {};
4357
4358    if (chain == nullptr || chain->iface != &llama_sampler_chain_i) {
4359        GGML_ABORT("%s: invalid sampler passed - requires a sampler created with llama_sampler_chain_init()\n", __func__);
4360    }
4361
4362    const auto * ctx = (const struct llama_sampler_chain *) chain->ctx;
4363
4364    data.t_sample_ms = 1e-3 * ctx->t_sample_us;
4365    data.n_sample    = std::max(0, ctx->n_sample);
4366
4367    return data;
4368}
4369
4370void llama_perf_sampler_print(const struct llama_sampler * chain) {
4371    const auto data = llama_perf_sampler(chain);
4372
4373    LLAMA_LOG_INFO("%s:    samplers time = %10.2f ms / %5d runs\n", __func__, data.t_sample_ms, data.n_sample);
4374}
4375
4376void llama_perf_sampler_reset(struct llama_sampler * chain) {
4377    if (chain == nullptr || chain->iface != &llama_sampler_chain_i) {
4378        GGML_ABORT("%s: invalid sampler passed - requires a sampler created with llama_sampler_chain_init()\n", __func__);
4379    }
4380
4381    auto * ctx = (struct llama_sampler_chain *) chain->ctx;
4382
4383    ctx->t_sample_us = 0;
4384    ctx->n_sample    = 0;
4385}