use crate::qwen::model::QwenModel;
use crate::utils::mask;
use candle_core::{Error as CandleError, Tensor};
use tracing::trace;
impl QwenModel {
pub fn create_embeddings_input_tensor(&self, tokens: &[i64]) -> Result<Tensor, CandleError> {
let padded_tokens = self.pad_tokens(tokens);
let shape = if let Some(input_shape) = self.config.embeddings_input_shape() {
let tensor_shape = (input_shape[0], input_shape[1]); trace!(
"🔍 SHAPE DEBUG: create_embeddings_input_tensor() - using ModelConfig shape: {:?} -> tensor shape: {:?}",
input_shape, tensor_shape
);
tensor_shape
} else {
let tensor_shape = (1, padded_tokens.len());
trace!(
"⚠️ SHAPE DEBUG: create_embeddings_input_tensor() - using fallback shape: {:?} (padded_tokens.len={})",
tensor_shape, padded_tokens.len()
);
tensor_shape
};
trace!(
"🎯 SHAPE DEBUG: Creating embeddings input tensor with shape {:?} for {} padded tokens (original: {} tokens)",
shape, padded_tokens.len(), tokens.len()
);
if shape.0 * shape.1 != padded_tokens.len() {
return Err(CandleError::Msg(format!(
"Shape mismatch: tensor shape {:?} requires {} elements, but got {} padded tokens",
shape,
shape.0 * shape.1,
padded_tokens.len()
)));
}
Tensor::from_vec(padded_tokens, shape, &self.config.device)
}
pub fn create_single_token_embeddings_input(&self, token: i64) -> Result<Tensor, CandleError> {
trace!(
"🔍 SINGLE TOKEN: Creating [1, 1] shape input tensor for token {}",
token
);
Tensor::from_vec(vec![token], (1, 1), &self.config.device)
}
pub fn create_position_tensor(&self, positions: Vec<i64>) -> Result<Tensor, CandleError> {
let expected_shape = if let Some(ffn_prefill_config) =
self.config.model_config.components.get("ffn_prefill")
{
ffn_prefill_config
.inputs
.get("position_ids")
.map(|position_ids_config| position_ids_config.shape.clone())
} else {
None
};
let (final_positions, shape) = if let Some(expected_shape) = expected_shape {
let expected_len = expected_shape[0];
if positions.len() == 1 {
let current_pos = positions[0];
let mut full_positions = (0..expected_len as i64).collect::<Vec<i64>>();
if current_pos >= 0 && (current_pos as usize) < expected_len {
for item in full_positions
.iter_mut()
.take(expected_len)
.skip(current_pos as usize + 1)
{
*item = 0;
}
}
trace!(
"Single token inference: creating position tensor with shape [{}] for current position {} (expected shape: {:?})",
expected_len, current_pos, expected_shape
);
(full_positions, (expected_len,))
} else {
let mut final_positions = positions;
if final_positions.len() > expected_len {
trace!(
"Truncating position tensor from {} to {} positions",
final_positions.len(),
expected_len
);
final_positions.truncate(expected_len);
} else if final_positions.len() < expected_len {
trace!(
"Padding position tensor from {} to {} positions",
final_positions.len(),
expected_len
);
final_positions.resize(expected_len, 0);
}
(final_positions, (expected_len,))
}
} else {
trace!("No FFN prefill position_ids shape found in ModelConfig, using legacy behavior");
let len = positions.len();
(positions, (len,))
};
trace!(
"Creating position tensor with shape {:?} for positions (len={}): {:?}",
shape,
final_positions.len(),
if final_positions.len() <= 10 {
format!("{final_positions:?}")
} else {
format!(
"[{}, {}, ..., {}]",
final_positions[0],
final_positions[1],
final_positions[final_positions.len() - 1]
)
}
);
Tensor::from_vec(final_positions, shape, &self.config.device)
}
pub fn create_causal_mask_tensor(
&self,
seq_len: usize,
context_len: usize,
) -> Result<Tensor, CandleError> {
let mut mask_data = vec![f32::NEG_INFINITY; seq_len * context_len];
for i in 0..seq_len {
for j in 0..=i.min(context_len - 1) {
mask_data[i * context_len + j] = 0.0;
}
}
let shape = (1, 1, seq_len, context_len);
trace!("Creating causal mask tensor with shape {:?}", shape);
Tensor::from_vec(mask_data, shape, &self.config.device)
}
pub fn create_update_mask_tensor(&self, position: usize) -> Result<Tensor, CandleError> {
let context_length = self.config.context_length();
let mut mask_data = vec![0.0f32; context_length];
if position < context_length {
mask_data[position] = 1.0;
}
let shape = (1, 1, context_length, 1);
trace!(
"Creating update mask tensor with shape {:?} for position {}",
shape,
position
);
Tensor::from_vec(mask_data, shape, &self.config.device)
}
pub fn create_position_causal_mask(
&self,
pos: usize,
context_length: usize,
) -> Result<Tensor, CandleError> {
self.config
.create_infer_causal_mask_tensor(pos, context_length)
}
pub fn create_update_mask(
&self,
pos: usize,
context_length: usize,
) -> Result<Tensor, CandleError> {
mask::create_update_mask(pos, context_length, &self.config.device)
}
}