Generate the next token. Assumes `prepare_prompt()` has been called for the first token.
(&mut self, index: usize)
| 395 | |
| 396 | /// Generate the next token. Assumes `prepare_prompt()` has been called for the first token. |
| 397 | pub async fn next_token(&mut self, index: usize) -> Result<Token> { |
| 398 | log::trace!("model.next_token({index})"); |
| 399 | |
| 400 | let num_tokens = self.tokens.len(); |
| 401 | let (context_size, context_index) = if self |
| 402 | .ctx |
| 403 | .cache |
| 404 | .as_ref() |
| 405 | .expect("No cache specified") |
| 406 | .with_kv_cache() |
| 407 | && index > 0 |
| 408 | { |
| 409 | (1, self.index_pos) |
| 410 | } else { |
| 411 | (num_tokens, 0) |
| 412 | }; |
| 413 | |
| 414 | let context_offset = num_tokens.saturating_sub(context_size); |
| 415 | let context_tokens = &self.tokens[context_offset..]; |
| 416 | let num_context_tokens = context_tokens.len(); |
| 417 | |
| 418 | let input = Tensor::new(context_tokens, &self.ctx.device)? |
| 419 | .unsqueeze(0) |
| 420 | .map_err(|e| anyhow!("error squeezing context tokens: {e}"))?; |
| 421 | |
| 422 | let logits = self |
| 423 | .forward(&input, context_index) |
| 424 | .await |
| 425 | .map_err(|e| anyhow!("error in model.forward: {e}"))?; |
| 426 | |
| 427 | let post_start = std::time::Instant::now(); |
| 428 | |
| 429 | let logits = logits |
| 430 | .squeeze(0) |
| 431 | .map_err(|e| anyhow!("error squeezing logits: {e}"))?; |
| 432 | |
| 433 | // Apply repeat penalty only to generated tokens (not prompt tokens) |
| 434 | let penalty_start = std::time::Instant::now(); |
| 435 | let logits = if self.ctx.args.repeat_penalty == 1. { |
| 436 | logits |
| 437 | } else { |
| 438 | let generated_start = self.prompt_len; |
| 439 | let penalty_tokens = &self.tokens[generated_start..]; |
| 440 | if penalty_tokens.is_empty() { |
| 441 | logits |
| 442 | } else { |
| 443 | let start_at = penalty_tokens |
| 444 | .len() |
| 445 | .saturating_sub(self.ctx.args.repeat_last_n); |
| 446 | apply_repeat_penalty_gpu( |
| 447 | &logits, |
| 448 | self.ctx.args.repeat_penalty, |
| 449 | &penalty_tokens[start_at..], |
| 450 | )? |
| 451 | } |
| 452 | }; |
| 453 | let penalty_elapsed = penalty_start.elapsed(); |
| 454 | self.index_pos += num_context_tokens; |
nothing calls this directly
no test coverage detected