Skip to main content

Gpt2

Struct Gpt2 

Source
pub struct Gpt2 {
    pub config: Gpt2Config,
    /* private fields */
}

Fields§

§config: Gpt2Config

Implementations§

Source§

impl Gpt2

Source

pub fn from_safetensors( path: impl AsRef<Path>, config: Gpt2Config, device: &Device, ) -> Result<Self>

Load HF GPT-2 weights. path is the .safetensors file. Weight names may or may not carry the “transformer.” prefix; both are accepted. The LM head is tied to wte (the checkpoint has no separate tensor).

Source

pub fn from_safetensors_bytes( bytes: &[u8], config: Gpt2Config, device: &Device, ) -> Result<Self>

Load HF GPT-2 weights from in-memory .safetensors bytes — the primary form; on wasm the bytes arrive from an HTTP fetch. wte never touches the device un-chunked: it is uploaded row-chunked straight from the file buffer (roadmap v4, pitfall 2).

Source

pub fn new_cache(&self) -> Result<KvCache>

Empty KV cache sized for this model’s full context.

Source

pub fn forward(&self, ids: &[u32]) -> Result<Tensor>

Full logits [t, vocab] — used by verification tests. The LM head is wte-tied: logits = h @ wte^T.

Source

pub fn logits_last(&self, ids: &[u32]) -> Result<Vec<f32>>

Logits for the last position only, recomputing the full context (no cache) — the reference decode path used by verification tests.

Source

pub fn logits_step(&self, ids: &[u32], cache: &mut KvCache) -> Result<Vec<f32>>

Last-position logits for ids continuing from cache (incremental decode: pass the full prompt once, then one token at a time).

Source

pub async fn logits_step_async( &self, ids: &[u32], cache: &mut KvCache, ) -> Result<Vec<f32>>

Async form of Gpt2::logits_step — identical math; the readback is awaited so it works on wasm32 (roadmap v4, pitfall 14).

Source

pub async fn logits_step_attn_async( &self, ids: &[u32], cache: &mut KvCache, ) -> Result<(Vec<f32>, Vec<AttnStep>)>

Gpt2::logits_step_async plus every block’s attention probabilities for this step, in layer order.

The cheap probe: exactly Gpt2::logits_step_trace_async with no detail layers and no top-n, so the two can never disagree about what the model attended with.

Source

pub async fn logits_step_trace_async( &self, ids: &[u32], cache: &mut KvCache, detail_layers: usize, top_n: usize, ) -> Result<(Vec<f32>, StepTrace)>

Gpt2::logits_step_async plus a full calculation trace for this step: the embedding, every block’s attention, the whole forward pass through the first detail_layers blocks (both LayerNorms, Q/K/V, pre-softmax scores, the concatenated heads and their projection, both residual adds, post-GELU MLP), the final LayerNorm, and the top_n most likely next tokens with their probabilities.

The logits are identical to logits_step_async — the probe only reads tensors the step computes anyway. The whole step is enqueued first, and every captured tensor comes back in a single batched readback: one at a time they cost ~2.7x the decode itself, since the price is the round trip rather than the bytes.

detail_layers is the cost knob. At 0 this is the attention-only probe and nothing but the post-softmax tensors is read. Each detail layer adds q_len * (13 * n_embd + n_head * kv_len) floats, so a long prefill is the only expensive call — a decode step is q_len == 1.

Source

pub fn init_random( config: Gpt2Config, device: &Device, seed: u64, ) -> Result<Gpt2>

Random initialization for training from scratch: N(0, 0.02) weights, residual projections scaled by 1/sqrt(2*n_layer), zero biases, identity LayerNorms.

Source

pub fn param_specs(&self) -> Vec<(String, bool)>

Parameter names (safetensors keys) and weight-decay flags, in the canonical order used by params, params_mut, and loss_grads.

Source

pub fn params(&self) -> Result<Vec<&Tensor>>

Parameters in param_specs order.

Source

pub fn params_mut(&mut self) -> Result<Vec<&mut Tensor>>

Mutable parameters in param_specs order (for the optimizer).

Source

pub fn save_safetensors(&self, path: impl AsRef<Path>) -> Result<()>

Save a checkpoint loadable by from_safetensors. A chunked wte is reassembled host-side first.

Source

pub fn loss(&self, input: &[u32], targets: &[u32]) -> Result<f32>

Mean cross-entropy of targets given input, forward only — no tape, no gradients, no dropout. This is the evaluation path: a validation split scored with Gpt2::loss_grads would build and discard a full backward graph per window.

Source

pub fn loss_grads( &self, input: &[u32], targets: &[u32], dropout_p: f32, seed: u32, ) -> Result<(f32, Vec<Tensor>)>

One training forward + backward on a single sequence: mean cross-entropy of targets given input, and gradients for every parameter in param_specs order. Batching is achieved by accumulating grads over calls (roadmap v4 batching policy).

Source

pub fn generate( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, ) -> Result<String>

Autoregressive generation with KV-cache decode. Returns the full text (prompt + completion).

Source

pub fn generate_streaming( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_token: impl FnMut(u32, &str), ) -> Result<String>

Sync streaming generation with KV-cache decode. on_token fires exactly once per generated token (never for the prompt) with the token id and the newly decodable text delta — which may be empty when a multi-byte character spans several BPE tokens, since a partial UTF-8 sequence is held back until its trailing bytes arrive.

This is the accurate throughput hook: callback invocations map 1:1 to tokens, unlike Gpt2::generate_async’s text-delta callback.

Source

pub fn generate_streaming_ctl( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_token: impl FnMut(u32, &str) -> ControlFlow<()>, ) -> Result<String>

Gpt2::generate_streaming with an interruptible callback: returning ControlFlow::Break stops after the current token and returns the text generated so far. Long interactive runs need this — a callback that cannot abort can only be “cancelled” once the whole run finishes.

Source

pub async fn generate_async( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_text: impl FnMut(&str), ) -> Result<String>

Async autoregressive generation with KV-cache decode — the browser form of Gpt2::generate. on_text receives each newly decoded text fragment (the delta of the full decode, so multi-byte characters that span BPE tokens are never split) so a page can stream output.

Source

pub async fn generate_async_ctl( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_text: impl FnMut(&str) -> ControlFlow<()>, ) -> Result<String>

Gpt2::generate_async with an interruptible callback — the async counterpart of Gpt2::generate_streaming_ctl. Returning ControlFlow::Break stops after the current token, which is how a page offers a working “stop” button.

Source

pub async fn generate_async_probe( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_text: impl FnMut(&str) -> ControlFlow<()>, on_attn: Option<impl FnMut(&[AttnStep])>, ) -> Result<String>

Gpt2::generate_async_ctl with an optional attention probe: on_attn, when present, fires once per decode step with every block’s attention probabilities — including the prompt prefill, whose q_len is the prompt length rather than 1.

Opt-in because it costs one readback per block per token. Passing None is exactly the non-probing path; the generated text is identical either way, since the probe reads tensors the step already computed.

Source

pub async fn generate_async_trace( &self, tokenizer: &impl Tokenizer, prompt: &str, max_new_tokens: usize, sampling: Sampling, on_text: impl FnMut(&str) -> ControlFlow<()>, on_trace: Option<impl FnMut(&StepTrace)>, detail_layers: usize, top_n: usize, ) -> Result<String>

Gpt2::generate_async_probe with the full calculation trace: on_trace, when present, fires once per step — including the prompt prefill, whose q_len is the prompt length rather than 1 — with everything Gpt2::logits_step_trace_async captured.

None is byte-for-byte the non-probing path. With Some, the generated text is still identical: the probe reads tensors the step already computed and changes no arithmetic.

Auto Trait Implementations§

§

impl !RefUnwindSafe for Gpt2

§

impl !UnwindSafe for Gpt2

§

impl Freeze for Gpt2

§

impl Send for Gpt2

§

impl Sync for Gpt2

§

impl Unpin for Gpt2

§

impl UnsafeUnpin for Gpt2

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast<T> for T

Source§

fn downcast(&self) -> &T

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> Upcast<T> for T

Source§

fn upcast(&self) -> Option<&T>

Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WasmNotSend for T
where T: Send,

Source§

impl<T> WasmNotSendSync for T

Source§

impl<T> WasmNotSync for T
where T: Sync,