kalosm_language_model/model/
generation_parameters.rs1#[cfg(feature = "sample")]
2use std::hash::Hash;
3#[cfg(feature = "sample")]
4use std::hash::Hasher;
5
6#[cfg(feature = "sample")]
7use llm_samplers::configure::SamplerChainBuilder;
8#[cfg(feature = "sample")]
9use llm_samplers::prelude::*;
10
11#[derive(Debug)]
13pub struct GenerationParameters {
14 pub(crate) temperature: f32,
15 pub(crate) tau: f32,
16 pub(crate) eta: f32,
17 pub(crate) mu: f32,
18 pub(crate) top_p: f64,
19 pub(crate) top_k: u32,
20 pub(crate) repetition_penalty: f32,
21 pub(crate) repetition_penalty_range: u32,
22 pub(crate) max_length: u32,
23 pub(crate) stop_on: Option<String>,
24 pub(crate) seed: Option<u64>,
25 #[cfg(feature = "sample")]
26 sampler: Option<(u64, SamplerChain)>,
27}
28
29impl PartialEq for GenerationParameters {
30 fn eq(&self, other: &Self) -> bool {
31 self.temperature == other.temperature
32 && self.eta == other.eta
33 && self.tau == other.tau
34 && self.mu == other.mu
35 && self.top_p == other.top_p
36 && self.repetition_penalty == other.repetition_penalty
37 && self.repetition_penalty_range == other.repetition_penalty_range
38 && self.max_length == other.max_length
39 && self.stop_on == other.stop_on
40 }
41}
42
43impl Clone for GenerationParameters {
44 fn clone(&self) -> Self {
45 Self {
46 temperature: self.temperature,
47 eta: self.eta,
48 tau: self.tau,
49 mu: self.mu,
50 top_p: self.top_p,
51 top_k: self.top_k,
52 repetition_penalty: self.repetition_penalty,
53 repetition_penalty_range: self.repetition_penalty_range,
54 max_length: self.max_length,
55 stop_on: self.stop_on.clone(),
56 seed: None,
57 #[cfg(feature = "sample")]
58 sampler: None,
59 }
60 }
61}
62
63impl Default for GenerationParameters {
64 fn default() -> Self {
65 Self::new()
66 }
67}
68
69#[cfg(feature = "sample")]
70impl Sampler for GenerationParameters {
71 fn sample<'a>(
72 &mut self,
73 res: &mut dyn HasSamplerResources,
74 logits: &'a mut Logits,
75 ) -> anyhow::Result<&'a mut Logits> {
76 self.with_sampler(|sampler| sampler.sample(res, logits))
77 }
78
79 fn sample_token(
80 &mut self,
81 res: &mut dyn HasSamplerResources,
82 logits: &mut Logits,
83 ) -> anyhow::Result<Option<TID>> {
84 self.with_sampler(|sampler| sampler.sample_token(res, logits))
85 }
86
87 fn sampled_token_id(&self) -> Option<TID> {
88 self.sampler().sampled_token_id()
89 }
90}
91
92impl GenerationParameters {
93 pub const fn new() -> Self {
95 Self {
96 temperature: 0.8,
97 eta: 0.1,
98 tau: 5.,
99 mu: 10.,
100 top_p: 1.0,
101 top_k: 1,
102 repetition_penalty: 1.3,
103 repetition_penalty_range: 64,
104 max_length: u32::MAX,
105 stop_on: None,
106 seed: None,
107 #[cfg(feature = "sample")]
108 sampler: None,
109 }
110 }
111
112 #[cfg(feature = "sample")]
113 fn with_sampler<O>(&mut self, with_sampler: impl FnOnce(&mut SamplerChain) -> O) -> O {
114 let mut hash = std::collections::hash_map::DefaultHasher::new();
115 self.eta.to_le_bytes().hash(&mut hash);
116 self.mu.to_le_bytes().hash(&mut hash);
117 self.repetition_penalty.to_le_bytes().hash(&mut hash);
118 self.repetition_penalty_range.hash(&mut hash);
119 self.tau.to_le_bytes().hash(&mut hash);
120 self.top_p.to_le_bytes().hash(&mut hash);
121 self.temperature.to_le_bytes().hash(&mut hash);
122 self.max_length.hash(&mut hash);
123 let hash = hash.finish();
124 if let Some((old_hash, sampler)) = &mut self.sampler {
125 if *old_hash == hash {
126 return with_sampler(sampler);
127 }
128 }
129 let mut sampler = self.sampler();
130 let output = with_sampler(&mut sampler);
131 self.sampler = Some((hash, sampler));
132 output
133 }
134
135 #[cfg(feature = "sample")]
136 pub fn sampler(&self) -> SamplerChain {
138 use llm_samplers::configure::SamplerSlot;
139 let GenerationParameters {
140 temperature,
141 tau,
142 eta,
143 mu,
144 repetition_penalty,
145 repetition_penalty_range,
146 top_p: _,
147 max_length: _,
148 stop_on: _,
149 ..
150 } = self;
151 let temperature = *temperature;
152 let tau = *tau;
153 let eta = *eta;
154 let mu = *mu;
155 let repetition_penalty = *repetition_penalty;
156 let repetition_penalty_range = *repetition_penalty_range;
157 SamplerChainBuilder::from([
158 (
159 "repetition",
160 SamplerSlot::new_static(move || {
161 Box::new(
162 SampleRepetition::default()
163 .penalty(repetition_penalty)
164 .last_n(repetition_penalty_range as usize),
165 )
166 }),
167 ),
168 (
169 "freqpresence",
170 SamplerSlot::new_static(move || Box::new(SampleFreqPresence::default().last_n(64))),
171 ),
172 (
173 "seqrepetition",
174 SamplerSlot::new_static(move || Box::<SampleSeqRepetition>::default()),
175 ),
176 (
177 "temperature",
178 SamplerSlot::new_static(move || {
179 Box::new(SampleTemperature::default().temperature(temperature))
180 }),
181 ),
182 (
183 "mirostat2",
184 SamplerSlot::new_static(move || {
185 Box::new(SampleMirostat2::default().tau(tau).eta(eta).mu(mu))
186 }),
187 ),
188 ])
189 .into_chain()
190 }
191
192 pub fn with_top_p(mut self, top_p: f64) -> Self {
194 self.top_p = top_p;
195 self
196 }
197
198 pub fn with_top_k(mut self, top_k: u32) -> Self {
200 self.top_k = top_k;
201 self
202 }
203
204 #[cfg(feature = "sample")]
205 pub fn mirostat2_sampler(self) -> SampleMirostat2 {
207 SampleMirostat2::default()
208 .tau(self.tau)
209 .eta(self.eta)
210 .mu(self.mu)
211 }
212
213 #[cfg(feature = "sample")]
214 pub fn bias_only_sampler(self) -> SamplerChain {
216 use llm_samplers::configure::SamplerSlot;
217 let GenerationParameters {
218 temperature,
219 repetition_penalty,
220 repetition_penalty_range,
221 ..
222 } = self;
223 SamplerChainBuilder::from([
224 (
225 "repetition",
226 SamplerSlot::new_static(move || {
227 Box::new(
228 SampleRepetition::default()
229 .penalty(repetition_penalty)
230 .last_n(repetition_penalty_range as usize),
231 )
232 }),
233 ),
234 (
235 "freqpresence",
236 SamplerSlot::new_static(move || Box::new(SampleFreqPresence::default().last_n(64))),
237 ),
238 (
239 "seqrepetition",
240 SamplerSlot::new_static(move || Box::<SampleSeqRepetition>::default()),
241 ),
242 (
243 "temperature",
244 SamplerSlot::new_static(move || {
245 Box::new(SampleTemperature::default().temperature(temperature))
246 }),
247 ),
248 ])
249 .into_chain()
250 }
251
252 pub fn with_temperature(mut self, temperature: f32) -> Self {
254 self.temperature = temperature;
255 self
256 }
257
258 pub fn with_tau(mut self, tau: f32) -> Self {
260 self.tau = tau;
261 self
262 }
263
264 pub fn with_eta(mut self, eta: f32) -> Self {
266 self.eta = eta;
267 self
268 }
269
270 pub fn with_mu(mut self, mu: f32) -> Self {
272 self.mu = mu;
273 self
274 }
275
276 pub fn with_repetition_penalty(mut self, repetition_penalty: f32) -> Self {
278 self.repetition_penalty = repetition_penalty;
279 self
280 }
281
282 pub fn with_repetition_penalty_range(mut self, repetition_penalty_range: u32) -> Self {
284 self.repetition_penalty_range = repetition_penalty_range;
285 self
286 }
287
288 pub fn with_max_length(mut self, max_length: u32) -> Self {
290 self.max_length = max_length;
291 self
292 }
293
294 pub fn with_stop_on(mut self, stop_on: impl Into<Option<String>>) -> Self {
296 self.stop_on = stop_on.into();
297 self
298 }
299
300 pub fn with_seed(mut self, seed: impl Into<Option<u64>>) -> Self {
302 self.seed = seed.into();
303 self
304 }
305
306 pub fn temperature(&self) -> f32 {
308 self.temperature
309 }
310
311 pub fn tau(&self) -> f32 {
313 self.tau
314 }
315
316 pub fn eta(&self) -> f32 {
318 self.eta
319 }
320
321 pub fn mu(&self) -> f32 {
323 self.mu
324 }
325
326 pub fn repetition_penalty(&self) -> f32 {
328 self.repetition_penalty
329 }
330
331 pub fn repetition_penalty_range(&self) -> u32 {
333 self.repetition_penalty_range
334 }
335
336 pub fn max_length(&self) -> u32 {
338 self.max_length
339 }
340
341 pub fn stop_on(&self) -> Option<&str> {
343 self.stop_on.as_deref()
344 }
345
346 pub fn seed(&self) -> Option<u64> {
348 self.seed
349 }
350}