1use core::cmp::Ordering;
2
3use crate::candidates::{candidate_order, Candidates, Error};
4use crate::rng::{unit, Rng};
5
6pub struct SamplerCtx<'a> {
8 pub rng: &'a mut dyn Rng,
10 pub history: &'a [u32],
12}
13
14impl core::fmt::Debug for SamplerCtx<'_> {
15 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16 formatter
17 .debug_struct("SamplerCtx")
18 .field("rng", &"dyn Rng")
19 .field("history", &self.history)
20 .finish()
21 }
22}
23
24pub trait Sampler: Send {
26 fn apply(&mut self, candidates: &mut Candidates, ctx: &mut SamplerCtx<'_>)
28 -> Result<(), Error>;
29
30 fn reset(&mut self) {}
32}
33
34#[derive(Clone, Copy, Debug, PartialEq)]
36pub struct Temperature {
37 pub t: f32,
39}
40
41impl Default for Temperature {
42 fn default() -> Self {
43 Self { t: 0.8 }
44 }
45}
46
47impl Sampler for Temperature {
48 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
49 apply_temperature(candidates, self.t);
50 Ok(())
51 }
52}
53
54#[derive(Clone, Copy, Debug, PartialEq)]
56pub struct DynTemperature {
57 pub t: f32,
59 pub delta: f32,
61 pub exponent: f32,
63}
64
65impl Default for DynTemperature {
66 fn default() -> Self {
67 Self {
68 t: 0.8,
69 delta: 0.0,
70 exponent: 1.0,
71 }
72 }
73}
74
75impl Sampler for DynTemperature {
76 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
77 if !self.delta.is_finite() || self.delta <= 0.0 {
78 apply_temperature(candidates, self.t);
79 return Ok(());
80 }
81 if candidates.buf.len() <= 1 {
82 return Ok(());
83 }
84
85 let min_t = (self.t as f64 - self.delta as f64).max(0.0);
86 let max_t = self.t as f64 + self.delta as f64;
87 candidates.softmax(true)?;
88 let entropy = candidates
89 .buf
90 .iter()
91 .filter(|candidate| candidate.p > 0.0)
92 .map(|candidate| {
93 let p = candidate.p as f64;
94 -p * p.ln()
95 })
96 .sum::<f64>();
97 let max_entropy = (candidates.buf.len() as f64).ln();
98 let exponent = if self.exponent.is_finite() {
99 self.exponent as f64
100 } else {
101 1.0
102 };
103 let normalized = (entropy / max_entropy).powf(exponent);
104 let dynamic = min_t + (max_t - min_t) * normalized;
105 let dynamic = if dynamic.is_nan() {
106 self.t
107 } else {
108 finite_f32(dynamic)
109 };
110 apply_temperature(candidates, dynamic);
111 candidates.softmax(false)
112 }
113}
114
115#[derive(Clone, Copy, Debug, PartialEq, Eq)]
117pub struct TopK {
118 pub k: i32,
120}
121
122impl Default for TopK {
123 fn default() -> Self {
124 Self { k: 40 }
125 }
126}
127
128impl Sampler for TopK {
129 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
130 apply_top_k(candidates, self.k);
131 Ok(())
132 }
133}
134
135#[derive(Clone, Copy, Debug, PartialEq)]
137pub struct TopP {
138 pub p: f32,
140 pub min_keep: usize,
142}
143
144impl Default for TopP {
145 fn default() -> Self {
146 Self {
147 p: 0.95,
148 min_keep: 0,
149 }
150 }
151}
152
153impl Sampler for TopP {
154 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
155 if self.p.is_nan() || self.p >= 1.0 {
156 return Ok(());
157 }
158 candidates.softmax(false)?;
159 if candidates.sorted {
160 truncate_top_p(candidates, self.p, self.min_keep);
161 return Ok(());
162 }
163
164 let len = candidates.buf.len();
165 let minimum = self.min_keep.max(1).min(len);
166 let mut prefix = minimum.max(32).min(len);
167 loop {
168 if prefix < len {
169 candidates
170 .buf
171 .select_nth_unstable_by(prefix, candidate_order);
172 candidates.buf[..prefix].sort_unstable_by(candidate_order);
173 } else {
174 candidates.buf.sort_unstable_by(candidate_order);
175 }
176
177 let mut cumulative = 0.0_f64;
178 for (index, candidate) in candidates.buf[..prefix].iter().enumerate() {
179 cumulative += candidate.p as f64;
180 if cumulative >= self.p as f64 && index + 1 >= minimum {
181 candidates.buf.truncate(index + 1);
182 candidates.sorted = true;
183 return Ok(());
184 }
185 }
186 if prefix == len {
187 candidates.sorted = true;
188 return Ok(());
189 }
190
191 let estimated = if cumulative > 0.0 && self.p > 0.0 {
192 ((prefix as f64 * self.p as f64 / cumulative).ceil() as usize).min(len)
193 } else {
194 prefix.saturating_mul(2).min(len)
195 };
196 prefix = estimated.max(prefix + 1).max(minimum).min(len);
197 }
198 }
199}
200
201#[derive(Clone, Copy, Debug, PartialEq)]
203pub struct MinP {
204 pub p: f32,
206 pub min_keep: usize,
208}
209
210impl Default for MinP {
211 fn default() -> Self {
212 Self {
213 p: 0.05,
214 min_keep: 0,
215 }
216 }
217}
218
219impl Sampler for MinP {
220 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
221 if self.p.is_nan() || self.p <= 0.0 || candidates.buf.is_empty() {
222 return Ok(());
223 }
224
225 if !candidates.sorted {
226 let max_logit = candidates
227 .buf
228 .iter()
229 .map(|candidate| candidate.logit)
230 .fold(f32::NEG_INFINITY, f32::max);
231 let min_logit = max_logit + self.p.ln();
232 let matching = candidates
233 .buf
234 .iter()
235 .filter(|candidate| candidate.logit >= min_logit)
236 .count();
237 if matching > 0 && matching >= self.min_keep {
238 candidates
239 .buf
240 .retain(|candidate| candidate.logit >= min_logit);
241 return Ok(());
242 }
243 candidates.sort_desc();
244 }
245
246 let min_logit = candidates.buf[0].logit + self.p.ln();
247 let mut keep = 1;
248 while keep < candidates.buf.len()
249 && (candidates.buf[keep].logit >= min_logit || keep < self.min_keep)
250 {
251 keep += 1;
252 }
253 candidates.buf.truncate(keep);
254 Ok(())
255 }
256}
257
258#[derive(Clone, Copy, Debug, PartialEq)]
260pub struct Typical {
261 pub p: f32,
263 pub min_keep: usize,
265}
266
267impl Default for Typical {
268 fn default() -> Self {
269 Self {
270 p: 1.0,
271 min_keep: 0,
272 }
273 }
274}
275
276impl Sampler for Typical {
277 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
278 if self.p.is_nan() || self.p >= 1.0 {
279 return Ok(());
280 }
281 candidates.softmax(true)?;
282 let entropy = candidates
283 .buf
284 .iter()
285 .filter(|candidate| candidate.p > 0.0)
286 .map(|candidate| {
287 let p = candidate.p as f64;
288 -p * p.ln()
289 })
290 .sum::<f64>();
291 candidates.buf.sort_unstable_by(|left, right| {
292 typical_score(left.p, entropy)
293 .total_cmp(&typical_score(right.p, entropy))
294 .then_with(|| left.id.cmp(&right.id))
295 });
296 let mut cumulative = 0.0_f64;
297 let mut keep = candidates.buf.len();
298 for (index, candidate) in candidates.buf.iter().enumerate() {
299 cumulative += candidate.p as f64;
300 if cumulative > self.p as f64 && (self.min_keep == 0 || index >= self.min_keep - 1) {
301 keep = index + 1;
302 break;
303 }
304 }
305 candidates.buf.truncate(keep);
306 candidates.sorted = false;
307 Ok(())
308 }
309}
310
311#[derive(Clone, Copy, Debug, PartialEq)]
313pub struct TailFree {
314 pub z: f32,
316 pub min_keep: usize,
318}
319
320impl Default for TailFree {
321 fn default() -> Self {
322 Self {
323 z: 1.0,
324 min_keep: 0,
325 }
326 }
327}
328
329impl Sampler for TailFree {
330 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
331 if self.z.is_nan() || self.z >= 1.0 || candidates.buf.len() <= 2 {
332 return Ok(());
333 }
334 candidates.softmax(true)?;
335 let second_difference = |index: usize| {
336 let first = candidates.buf[index].p - candidates.buf[index + 1].p;
337 let next = candidates.buf[index + 1].p - candidates.buf[index + 2].p;
338 (first - next).abs() as f64
339 };
340 let count = candidates.buf.len() - 2;
341 let sum = (0..count).map(second_difference).sum::<f64>();
342 let mut cumulative = 0.0;
343 let mut keep = candidates.buf.len();
344 for index in 0..count {
345 let value = if sum > 1e-6 {
346 second_difference(index) / sum
347 } else {
348 1.0 / count as f64
349 };
350 cumulative += value;
351 if cumulative > self.z as f64 && index >= self.min_keep {
352 keep = index.max(1);
353 break;
354 }
355 }
356 candidates.buf.truncate(keep);
357 Ok(())
358 }
359}
360
361#[derive(Clone, Copy, Debug, PartialEq)]
363pub struct Xtc {
364 pub probability: f32,
366 pub threshold: f32,
368 pub min_keep: usize,
370}
371
372impl Default for Xtc {
373 fn default() -> Self {
374 Self {
375 probability: 0.0,
376 threshold: 0.1,
377 min_keep: 0,
378 }
379 }
380}
381
382impl Sampler for Xtc {
383 fn apply(
384 &mut self,
385 candidates: &mut Candidates,
386 ctx: &mut SamplerCtx<'_>,
387 ) -> Result<(), Error> {
388 if self.probability.is_nan()
389 || self.threshold.is_nan()
390 || self.probability <= 0.0
391 || self.threshold > 0.5
392 || candidates.buf.len() < 2
393 {
394 return Ok(());
395 }
396 if unit(ctx.rng) > self.probability as f64 {
397 return Ok(());
398 }
399 candidates.softmax(true)?;
400 let mut pos_last = 0;
401 for (index, candidate) in candidates.buf.iter().enumerate() {
402 if candidate.p > 0.0 && candidate.p >= self.threshold {
403 pos_last = index;
404 } else {
405 break;
406 }
407 }
408 if pos_last > 0 && candidates.buf.len() - pos_last >= self.min_keep {
409 candidates.buf.drain(..pos_last);
410 }
411 Ok(())
412 }
413}
414
415#[derive(Clone, Copy, Debug, PartialEq)]
417pub struct Penalties {
418 pub last_n: i32,
420 pub repeat: f32,
422 pub freq: f32,
424 pub presence: f32,
426}
427
428impl Default for Penalties {
429 fn default() -> Self {
430 Self {
431 last_n: 64,
432 repeat: 1.0,
433 freq: 0.0,
434 presence: 0.0,
435 }
436 }
437}
438
439impl Sampler for Penalties {
440 fn apply(
441 &mut self,
442 candidates: &mut Candidates,
443 ctx: &mut SamplerCtx<'_>,
444 ) -> Result<(), Error> {
445 if self.last_n <= 0 || (self.repeat == 1.0 && self.freq == 0.0 && self.presence == 0.0) {
446 return Ok(());
447 }
448 let window_len = ctx.history.len().min(self.last_n as usize);
449 if candidates.counts.capacity() < window_len {
450 candidates
451 .counts
452 .reserve_exact(window_len - candidates.counts.capacity());
453 }
454 candidates.counts.clear();
455 candidates.counts.extend(
456 ctx.history[ctx.history.len() - window_len..]
457 .iter()
458 .map(|&token| (token, 1)),
459 );
460 candidates.counts.sort_unstable_by_key(|entry| entry.0);
461 coalesce_counts(&mut candidates.counts);
462
463 let repeat = if self.repeat.is_finite() && self.repeat > 0.0 {
464 self.repeat
465 } else {
466 1.0
467 };
468 let frequency = if self.freq.is_finite() {
469 self.freq
470 } else {
471 0.0
472 };
473 let presence = if self.presence.is_finite() {
474 self.presence
475 } else {
476 0.0
477 };
478 for candidate in &mut candidates.buf {
479 let index = match candidates
480 .counts
481 .binary_search_by_key(&candidate.id, |entry| entry.0)
482 {
483 Ok(index) => index,
484 Err(_) => continue,
485 };
486 let count = candidates.counts[index].1 as f32;
487 if candidate.logit == f32::NEG_INFINITY {
488 continue;
489 }
490 let repeated = if candidate.logit <= 0.0 {
491 candidate.logit as f64 * repeat as f64
492 } else {
493 candidate.logit as f64 / repeat as f64
494 };
495 candidate.logit =
496 finite_f32(repeated - count as f64 * frequency as f64 - presence as f64);
497 }
498 candidates.sorted = false;
499 Ok(())
500 }
501}
502
503#[derive(Clone, Debug, PartialEq)]
505pub struct Dry {
506 pub multiplier: f32,
508 pub base: f32,
510 pub allowed_length: i32,
512 pub last_n: i32,
514 pub breakers: Vec<Vec<u32>>,
516}
517
518impl Default for Dry {
519 fn default() -> Self {
520 Self {
521 multiplier: 0.0,
522 base: 1.75,
523 allowed_length: 2,
524 last_n: 64,
525 breakers: Vec::new(),
526 }
527 }
528}
529
530impl Sampler for Dry {
531 fn apply(
532 &mut self,
533 candidates: &mut Candidates,
534 ctx: &mut SamplerCtx<'_>,
535 ) -> Result<(), Error> {
536 if !self.multiplier.is_finite()
537 || !self.base.is_finite()
538 || self.multiplier == 0.0
539 || self.base < 1.0
540 || self.last_n <= 0
541 {
542 return Ok(());
543 }
544 let allowed = self.allowed_length.max(0) as usize;
545 let n = ctx.history.len().min(self.last_n as usize);
546 if n <= allowed {
547 return Ok(());
548 }
549 let history = &ctx.history[ctx.history.len() - n..];
550 if candidates.breaker_indices.capacity() < self.breakers.len() {
551 candidates
552 .breaker_indices
553 .reserve_exact(self.breakers.len() - candidates.breaker_indices.capacity());
554 }
555 candidates.breaker_indices.clear();
556 candidates.breaker_indices.extend(
557 self.breakers
558 .iter()
559 .enumerate()
560 .filter_map(|(index, sequence)| (!sequence.is_empty()).then_some(index)),
561 );
562 candidates
563 .breaker_indices
564 .sort_unstable_by(|&left, &right| {
565 breaker_order(&self.breakers[left], &self.breakers[right])
566 });
567
568 let recent = |offset: usize| history[n - 1 - offset];
569 let mut repeat_limit = n;
570 for index in 0..n {
571 let token = recent(index);
572 let range = breaker_range(&self.breakers, &candidates.breaker_indices, token);
573 let mut longest = None;
574 for &breaker_index in &candidates.breaker_indices[range] {
575 let sequence = &self.breakers[breaker_index];
576 let tail = &sequence[1..];
577 if tail.len() <= index
578 && longest.map_or(true, |length| tail.len() > length)
579 && tail
580 .iter()
581 .enumerate()
582 .all(|(offset, &expected)| expected == recent(index - offset - 1))
583 {
584 longest = Some(tail.len());
585 }
586 }
587 if let Some(length) = longest {
588 repeat_limit = index - length;
589 break;
590 }
591 }
592 if repeat_limit < allowed {
593 return Ok(());
594 }
595
596 if candidates.repeat_count.capacity() < n {
597 candidates
598 .repeat_count
599 .reserve_exact(n - candidates.repeat_count.capacity());
600 }
601 if candidates.max_repeats.capacity() < n {
602 candidates
603 .max_repeats
604 .reserve_exact(n - candidates.max_repeats.capacity());
605 }
606 candidates.repeat_count.clear();
607 candidates.repeat_count.resize(n, 0);
608 let last_index = n - 1;
609 let (mut left, mut right) = (0, 0);
610 for k in 1..n {
611 if k > right {
612 let mut matched = 0;
613 while matched + k < n && recent(matched) == recent(matched + k) {
614 matched += 1;
615 }
616 candidates.repeat_count[last_index - k] = matched.min(repeat_limit);
617 if matched > 0 {
618 left = k;
619 right = k + matched - 1;
620 }
621 } else {
622 let previous = k - left;
623 let available = right - k + 1;
624 if candidates.repeat_count[last_index - previous] < available {
625 candidates.repeat_count[last_index - k] =
626 candidates.repeat_count[last_index - previous].min(repeat_limit);
627 } else {
628 let mut index = right + 1;
629 while index < n && recent(index) == recent(index - k) {
630 index += 1;
631 }
632 candidates.repeat_count[last_index - k] = (index - k).min(repeat_limit);
633 left = k;
634 right = index - 1;
635 }
636 }
637 }
638
639 candidates.max_repeats.clear();
640 for index in 0..n - 1 {
641 let length = candidates.repeat_count[index];
642 if length < allowed {
643 continue;
644 }
645 let token = recent(n - 2 - index);
646 candidates.max_repeats.push((token, length));
647 }
648 candidates.max_repeats.sort_unstable_by_key(|entry| entry.0);
649 coalesce_max_repeats(&mut candidates.max_repeats);
650
651 let max_exponent = if self.base > 1.000_001 {
652 (88.722_84_f32 / self.base.ln()) as usize
653 } else {
654 0
655 };
656 for candidate in &mut candidates.buf {
657 let position = match candidates
658 .max_repeats
659 .binary_search_by_key(&candidate.id, |entry| entry.0)
660 {
661 Ok(position) => position,
662 Err(_) => continue,
663 };
664 let range = breaker_range(&self.breakers, &candidates.breaker_indices, candidate.id);
665 if candidates.breaker_indices[range]
666 .iter()
667 .any(|&index| self.breakers[index].len() == 1)
668 {
669 continue;
670 }
671 let mut exponent = candidates.max_repeats[position].1.saturating_sub(allowed);
672 if max_exponent > 0 {
673 exponent = exponent.min(max_exponent);
674 }
675 if candidate.logit != f32::NEG_INFINITY {
676 let penalty = self.multiplier as f64 * (self.base as f64).powi(exponent as i32);
677 candidate.logit = finite_f32(candidate.logit as f64 - penalty);
678 }
679 }
680 candidates.sorted = false;
681 Ok(())
682 }
683}
684
685#[derive(Clone, Debug, PartialEq)]
687pub struct MirostatV1 {
688 pub n_vocab: u32,
690 pub tau: f32,
692 pub eta: f32,
694 pub m: usize,
696 mu: f32,
697 last_k: usize,
698}
699
700impl MirostatV1 {
701 pub fn new(n_vocab: u32) -> Self {
703 Self {
704 n_vocab: n_vocab.max(1),
705 tau: 5.0,
706 eta: 0.1,
707 m: 100,
708 mu: 10.0,
709 last_k: 0,
710 }
711 }
712
713 pub fn mu(&self) -> f32 {
715 self.mu
716 }
717
718 #[cfg(test)]
719 pub(crate) fn last_k(&self) -> usize {
720 self.last_k
721 }
722}
723
724impl Sampler for MirostatV1 {
725 fn apply(
726 &mut self,
727 candidates: &mut Candidates,
728 ctx: &mut SamplerCtx<'_>,
729 ) -> Result<(), Error> {
730 candidates.softmax(true)?;
731 let pair_count = self
732 .m
733 .saturating_sub(1)
734 .min(candidates.buf.len().saturating_sub(1));
735 let (mut sum_tb, mut sum_tt) = (0.0_f64, 0.0_f64);
736 for index in 0..pair_count {
737 let t = (((index + 2) as f64) / ((index + 1) as f64)).ln();
738 let b = ((candidates.buf[index].p as f64) / (candidates.buf[index + 1].p as f64)).ln();
739 sum_tb += t * b;
740 sum_tt += t * t;
741 }
742 let slope = sum_tb / sum_tt;
743 let epsilon = slope - 1.0;
744 let numerator = epsilon * 2.0_f64.powf(self.mu as f64);
745 let denominator = 1.0 - (self.n_vocab as f64).powf(-epsilon);
746 let estimate = (numerator / denominator).powf(1.0 / slope);
747 let k = if estimate.is_finite() && estimate >= 1.0 {
748 estimate.min(i32::MAX as f64) as i32
749 } else {
750 1
751 };
752 self.last_k = k as usize;
753 apply_top_k(candidates, k);
754 candidates.softmax(true)?;
755 apply_dist(candidates, ctx.rng)?;
756 let selected = candidates.selected.ok_or(Error::AllMasked)?;
757 let surprise = -(candidates.buf[selected].p as f64).log2();
758 self.mu -= self.eta * (surprise as f32 - self.tau);
759 Ok(())
760 }
761
762 fn reset(&mut self) {
763 self.mu = 2.0 * self.tau;
764 self.last_k = 0;
765 }
766}
767
768#[derive(Clone, Debug, PartialEq)]
770pub struct MirostatV2 {
771 pub tau: f32,
773 pub eta: f32,
775 mu: f32,
776}
777
778impl MirostatV2 {
779 pub fn new(tau: f32, eta: f32) -> Self {
781 Self {
782 tau,
783 eta,
784 mu: 2.0 * tau,
785 }
786 }
787
788 pub fn mu(&self) -> f32 {
790 self.mu
791 }
792}
793
794impl Default for MirostatV2 {
795 fn default() -> Self {
796 Self::new(5.0, 0.1)
797 }
798}
799
800impl Sampler for MirostatV2 {
801 fn apply(
802 &mut self,
803 candidates: &mut Candidates,
804 ctx: &mut SamplerCtx<'_>,
805 ) -> Result<(), Error> {
806 candidates.softmax(true)?;
807 let mut keep = candidates.buf.len();
808 for (index, candidate) in candidates.buf.iter().enumerate() {
809 if -(candidate.p as f64).log2() > self.mu as f64 {
810 keep = index.max(1);
811 break;
812 }
813 }
814 candidates.buf.truncate(keep);
815 candidates.softmax(true)?;
816 apply_dist(candidates, ctx.rng)?;
817 let selected = candidates.selected.ok_or(Error::AllMasked)?;
818 let surprise = -(candidates.buf[selected].p as f64).log2();
819 self.mu -= self.eta * (surprise as f32 - self.tau);
820 Ok(())
821 }
822
823 fn reset(&mut self) {
824 self.mu = 2.0 * self.tau;
825 }
826}
827
828#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
830pub struct Greedy;
831
832impl Sampler for Greedy {
833 fn apply(&mut self, candidates: &mut Candidates, _: &mut SamplerCtx<'_>) -> Result<(), Error> {
834 if candidates.buf.is_empty() {
835 return Err(Error::AllMasked);
836 }
837 let mut selected: Option<usize> = None;
838 for (index, candidate) in candidates.buf.iter().enumerate() {
839 if !candidate.logit.is_finite() {
840 continue;
841 }
842 let is_larger = match selected {
843 Some(current) => {
844 candidate.logit.total_cmp(&candidates.buf[current].logit) == Ordering::Greater
845 }
846 None => true,
847 };
848 if is_larger {
849 selected = Some(index);
850 }
851 }
852 candidates.selected = selected;
853 selected.ok_or(Error::AllMasked).map(|_| ())
854 }
855}
856
857#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
859pub struct Dist;
860
861impl Sampler for Dist {
862 fn apply(
863 &mut self,
864 candidates: &mut Candidates,
865 ctx: &mut SamplerCtx<'_>,
866 ) -> Result<(), Error> {
867 apply_dist(candidates, ctx.rng)
868 }
869}
870
871fn apply_temperature(candidates: &mut Candidates, temperature: f32) {
872 if candidates.buf.is_empty() {
873 return;
874 }
875 if temperature.partial_cmp(&0.0) != Some(Ordering::Greater) {
876 let maximum = candidates
877 .buf
878 .iter()
879 .enumerate()
880 .filter(|(_, candidate)| candidate.logit.is_finite())
881 .max_by(|(left_index, left), (right_index, right)| {
882 left.logit
883 .total_cmp(&right.logit)
884 .then_with(|| right_index.cmp(left_index))
885 })
886 .map(|(index, _)| index);
887 for (index, candidate) in candidates.buf.iter_mut().enumerate() {
888 if Some(index) != maximum {
889 candidate.logit = f32::NEG_INFINITY;
890 }
891 }
892 return;
893 }
894
895 let would_overflow = temperature.is_finite()
896 && candidates.buf.iter().any(|candidate| {
897 candidate.logit.is_finite()
898 && (candidate.logit as f64 / temperature as f64).abs() > f32::MAX as f64
899 });
900 let offset = if would_overflow {
901 candidates
902 .buf
903 .iter()
904 .filter(|candidate| candidate.logit.is_finite())
905 .map(|candidate| candidate.logit)
906 .max_by(f32::total_cmp)
907 .unwrap_or(0.0)
908 } else {
909 0.0
910 };
911 for candidate in &mut candidates.buf {
912 if candidate.logit == f32::NEG_INFINITY {
913 continue;
914 }
915 candidate.logit = finite_f32((candidate.logit as f64 - offset as f64) / temperature as f64);
916 }
917}
918
919fn apply_top_k(candidates: &mut Candidates, k: i32) {
920 if k <= 0 || candidates.buf.is_empty() {
921 return;
922 }
923 let keep = (k as usize).min(candidates.buf.len());
924 if !candidates.sorted {
925 if keep < candidates.buf.len() {
926 candidates.buf.select_nth_unstable_by(keep, candidate_order);
927 candidates.buf[..keep].sort_unstable_by(candidate_order);
928 } else {
929 candidates.buf.sort_unstable_by(candidate_order);
930 }
931 candidates.sorted = true;
932 }
933 candidates.buf.truncate(keep);
934}
935
936fn apply_dist(candidates: &mut Candidates, rng: &mut dyn Rng) -> Result<(), Error> {
937 if candidates.buf.is_empty() {
938 return Err(Error::AllMasked);
939 }
940 if !candidates.sanitize_logits() {
941 return Err(Error::AllMasked);
942 }
943 let draw = unit(rng);
944 if candidates.buf.len() == 1 {
945 candidates.buf[0].p = 1.0;
946 candidates.selected = Some(0);
947 return Ok(());
948 }
949
950 let max_logit = candidates
951 .buf
952 .iter()
953 .map(|candidate| candidate.logit)
954 .fold(f32::NEG_INFINITY, f32::max);
955 let total = candidates
956 .buf
957 .iter()
958 .map(|candidate| ((candidate.logit - max_logit) as f64).exp())
959 .sum::<f64>();
960 if !total.is_finite() || total <= 0.0 {
961 return Err(Error::AllMasked);
962 }
963 let target = draw * total;
964 let mut running = 0.0;
965 let mut selected = None;
966 for (index, candidate) in candidates.buf.iter_mut().enumerate() {
967 let weight = ((candidate.logit - max_logit) as f64).exp();
968 candidate.p = (weight / total) as f32;
969 running += weight;
970 if selected.is_none() && weight > 0.0 && running >= target {
971 selected = Some(index);
972 }
973 }
974 candidates.selected = selected.or_else(|| {
975 candidates
976 .buf
977 .iter()
978 .enumerate()
979 .rev()
980 .find(|(_, candidate)| candidate.p > 0.0)
981 .map(|(index, _)| index)
982 });
983 candidates.selected.ok_or(Error::AllMasked).map(|_| ())
984}
985
986fn typical_score(probability: f32, entropy: f64) -> f64 {
987 if probability > 0.0 {
988 (-(probability as f64).ln() - entropy).abs()
989 } else {
990 f64::INFINITY
991 }
992}
993
994fn truncate_top_p(candidates: &mut Candidates, probability: f32, min_keep: usize) {
995 let minimum = min_keep.max(1).min(candidates.buf.len());
996 let mut cumulative = 0.0_f64;
997 let mut keep = candidates.buf.len();
998 for (index, candidate) in candidates.buf.iter().enumerate() {
999 cumulative += candidate.p as f64;
1000 if cumulative >= probability as f64 && index + 1 >= minimum {
1001 keep = index + 1;
1002 break;
1003 }
1004 }
1005 candidates.buf.truncate(keep);
1006}
1007
1008fn coalesce_counts(counts: &mut Vec<(u32, u32)>) {
1009 let mut write = 0;
1010 for read in 0..counts.len() {
1011 if write > 0 && counts[write - 1].0 == counts[read].0 {
1012 counts[write - 1].1 += counts[read].1;
1013 } else {
1014 counts[write] = counts[read];
1015 write += 1;
1016 }
1017 }
1018 counts.truncate(write);
1019}
1020
1021fn coalesce_max_repeats(repeats: &mut Vec<(u32, usize)>) {
1022 let mut write = 0;
1023 for read in 0..repeats.len() {
1024 if write > 0 && repeats[write - 1].0 == repeats[read].0 {
1025 repeats[write - 1].1 = repeats[write - 1].1.max(repeats[read].1);
1026 } else {
1027 repeats[write] = repeats[read];
1028 write += 1;
1029 }
1030 }
1031 repeats.truncate(write);
1032}
1033
1034fn finite_f32(value: f64) -> f32 {
1035 if value.is_nan() {
1036 f32::NEG_INFINITY
1037 } else if value > f32::MAX as f64 {
1038 f32::MAX
1039 } else if value < -(f32::MAX as f64) {
1040 -f32::MAX
1041 } else {
1042 value as f32
1043 }
1044}
1045
1046fn breaker_order(left: &[u32], right: &[u32]) -> Ordering {
1047 left.first()
1048 .cmp(&right.first())
1049 .then_with(|| right.len().cmp(&left.len()))
1050 .then_with(|| left.cmp(right))
1051}
1052
1053fn breaker_range(breakers: &[Vec<u32>], indices: &[usize], token: u32) -> core::ops::Range<usize> {
1054 let start = indices.partition_point(|&index| breakers[index].first().copied().unwrap() < token);
1055 let end = indices.partition_point(|&index| breakers[index].first().copied().unwrap() <= token);
1056 start..end
1057}