Forward pass through all blocks.
(&mut self, x: &Tensor, idx: usize)
| 264 | |
| 265 | /// Forward pass through all blocks. |
| 266 | pub async fn forward(&mut self, x: &Tensor, idx: usize) -> Result<Tensor> { |
| 267 | let forward_start = std::time::Instant::now(); |
| 268 | let (_batch_size, seq_len) = x.dims2()?; |
| 269 | |
| 270 | let emb_start = std::time::Instant::now(); |
| 271 | let mut x = self.ctx.backend.embedding(x, &self.embed_weight) |
| 272 | .map_err(|e| anyhow!("error in embedding: {e}"))?; |
| 273 | // Apply embedding scale if configured (Gemma scales by sqrt(hidden_size)). |
| 274 | if let Some(scale) = self.ctx.config.as_ref().and_then(|c| c.embed_scale) { |
| 275 | x = (x * scale as f64)?; |
| 276 | } |
| 277 | let emb_elapsed = emb_start.elapsed(); |
| 278 | |
| 279 | let num_blocks = self.blocks.len(); |
| 280 | let mut block_idx = 0; |
| 281 | let mut local_elapsed = std::time::Duration::ZERO; |
| 282 | let mut local_count: usize = 0; |
| 283 | |
| 284 | while block_idx < num_blocks { |
| 285 | let curr_block_id = self.blocks[block_idx].ident().to_owned(); |
| 286 | if curr_block_id == "local" { |
| 287 | let local_start = std::time::Instant::now(); |
| 288 | x = self.blocks[block_idx] |
| 289 | .forward_mut(&x, idx, block_idx, &mut self.ctx) |
| 290 | .await |
| 291 | .map_err(|e| { |
| 292 | anyhow!("error in forward operation of local block {block_idx}: {e}") |
| 293 | })?; |
| 294 | local_elapsed += local_start.elapsed(); |
| 295 | local_count += 1; |
| 296 | |
| 297 | block_idx += 1; |
| 298 | } else { |
| 299 | // collect all contiguous layers running on the same worker |
| 300 | let mut batch = vec![]; |
| 301 | let first = block_idx; |
| 302 | while block_idx < num_blocks && self.blocks[block_idx].ident() == curr_block_id { |
| 303 | batch.push(( |
| 304 | self.blocks[block_idx].layer_name().to_string(), |
| 305 | idx, |
| 306 | block_idx, |
| 307 | )); |
| 308 | block_idx += 1; |
| 309 | } |
| 310 | |
| 311 | let num_layers = batch.len(); |
| 312 | let batch_start = std::time::Instant::now(); |
| 313 | x = self.blocks[first] |
| 314 | .forward_batch(&x, batch, &mut self.ctx) |
| 315 | .await |
| 316 | .map_err(|e| { |
| 317 | anyhow!( |
| 318 | "error in forward batch for blocks {first}..{block_idx} on {}: {e}", |
| 319 | &curr_block_id |
| 320 | ) |
| 321 | })?; |
| 322 | let batch_elapsed = batch_start.elapsed(); |
| 323 | log::debug!( |
no test coverage detected