MCPcopy Create free account
hub / github.com/evilsocket/cake / apply_repeat_penalty_gpu

Function apply_repeat_penalty_gpu

cake-core/src/models/common/text_model.rs:60–99  ·  view source on GitHub ↗

Apply repeat penalty entirely on GPU to avoid costly GPU↔CPU round-trips. The upstream `candle_transformers::utils::apply_repeat_penalty` copies the entire logits tensor (vocab_size × 4 bytes ≈ 600 KB) to CPU, modifies a handful of elements, then copies everything back. This forces a full GPU synchronisation and two large PCIe transfers per token. This implementation stays on-device: it selects

(
    logits: &Tensor,
    penalty: f32,
    context: &[u32],
)

Source from the content-addressed store, hash-verified

58/// This implementation stays on-device: it selects only the penalty positions, computes
59/// sign-aware multipliers, and scatters the deltas back with `index_add`.
60fn apply_repeat_penalty_gpu(
61 logits: &Tensor,
62 penalty: f32,
63 context: &[u32],
64) -> Result<Tensor> {
65 // Deduplicate tokens (same semantics as the upstream version).
66 let mut seen = HashSet::new();
67 let unique: Vec<u32> = context
68 .iter()
69 .filter(|t| seen.insert(**t))
70 .copied()
71 .collect();
72
73 if unique.is_empty() {
74 return Ok(logits.clone());
75 }
76
77 let device = logits.device();
78 let dtype = logits.dtype();
79 let indices = Tensor::new(unique.as_slice(), device)?;
80
81 // Gather logits at penalty positions (N elements, tiny).
82 let selected = logits.index_select(&indices, 0)?;
83
84 // Sign-aware multiplier: 1/penalty for logits ≥ 0, penalty for logits < 0.
85 let is_non_negative = selected.ge(0f32)?;
86 let recip = Tensor::new(1.0f32 / penalty, device)?
87 .to_dtype(dtype)?
88 .broadcast_as(selected.shape())?;
89 let pen = Tensor::new(penalty, device)?
90 .to_dtype(dtype)?
91 .broadcast_as(selected.shape())?;
92 let mult = is_non_negative.where_cond(&recip, &pen)?;
93
94 // delta = selected * mult - selected (what to add to the original logits).
95 let penalized = (&selected * &mult)?;
96 let delta = (&penalized - &selected)?;
97
98 Ok(logits.index_add(&indices, &delta, 0)?)
99}
100
101/// Create the logit sampling logic from the context.
102pub fn create_logits_processor(ctx: &Context) -> LogitsProcessor {

Calls 5

dtypeMethod · 0.80
as_sliceMethod · 0.80
shapeMethod · 0.80
cloneMethod · 0.45
deviceMethod · 0.45