ELL3N HSU
← Project overview

ENGINEERING / WORKFLOW

From samples to adapters: SFT + LoRA

Follow ten modules through data gates, supervised training, low-rank adaptation and independent evaluation.

Educational simulation: examples are not training data. Playback does not measure runtime or predict model quality or performance.

Jump to the parameter lab ↓

A thick border marks the current step, dashed borders mark visited steps, and thin borders mark pending steps. Arrows show the teaching data flow.

PT01

Dataset Preparation

Reviewed inputs and a target Python file form one sample.

Input
Fictional scenario: an invalid request must preserve state.
Operation
Separate rules, scenario, API, framework and reference from the target; record source_group and approval.
Output
A traceable, approved training candidate.
Why it matters
The target is supervision, never an inference-time input.

Before: Start → After: Data Audit

PT02

Data Audit

Structural checks precede training; business correctness still needs review.

Input
Candidate rows and optional frozen benchmark manifests.
Operation
Validate required fields, split/group isolation, approval, duplicate targets and Python syntax. Check benchmark exclusion when configured.
Output
Validated rows; malformed or overlapping data is rejected.
Why it matters
An empty exclude_manifests list does not prove benchmark isolation.

Before: Dataset Preparation → After: Prompt Construction

PT03

Prompt Construction

Training and generation share common.messages().

Input
The five input sections, without the target.
Operation
Construct system and user messages; apply the locked tokenizer chat template.
Output
The prompt prefix used by encoding and generation.
Why it matters
A shared template prevents training and inference format drift.

Before: Data Audit → After: Tokenization & Label Mask

PT04

Tokenization & Label Mask

Prompt tokens condition predictions but are excluded from direct loss.

Input
Prompt plus assistant target.
Operation
Verify the prompt prefix, encode the complete sequence and mask prompt labels with -100. Reject overlong sequences instead of truncating.
Output
input_ids, attention_mask and completion-only labels.
Why it matters
Every sample must retain supervised tokens and a correct answer boundary.

Before: Prompt Construction → After: Forward Pass & SFT Loss

PT05

Forward Pass & SFT Loss

Trainer invokes the causal language model; train.py does not implement a custom forward loop.

Input
Encoded sequences and masked labels.
Operation
Teacher forcing predicts the next token. Conceptually, L = −Σ log P(y_t | x, y_<t) / T over valid target positions; the model shifts logits and labels.
Output
A scalar supervised loss and an autograd graph.
Why it matters
Token loss supplies a training signal; it does not establish business correctness.

Before: Tokenization & Label Mask → After: Backward & Gradient Accumulation

PT06

Backward & Gradient Accumulation

Trainer/PyTorch manages differentiation and accumulation.

Input
Loss for successive micro-batches.
Operation
Backpropagate into trainable LoRA parameters; accumulate gradients until an optimizer update is due. The project fixes micro-batch size to 1.
Output
Accumulated gradients for the optimizer.
Why it matters
A micro-batch forward/backward is not necessarily one optimizer step.

Before: Forward Pass & SFT Loss → After: AdamW & LR Scheduler

PT07

AdamW & LR Scheduler

The project selects adamw_torch through TrainingArguments.

Input
Accumulated gradients, moment estimates and current learning rate.
Operation
AdamW updates trainable parameters, then the scheduler advances and gradients are cleared. Transformers 4.57.1 defaults to linear decay with no warmup here.
Output
Updated LoRA weights and the next learning rate.
Why it matters
Changing max_steps changes both training duration and the linear decay trajectory.

Before: Backward & Gradient Accumulation → After: LoRA Parameter Update & Adapter

PT08

LoRA Parameter Update & Adapter

LoRA is attached before training; this step inspects the update and final saved artifact.

Input
Frozen base W and trainable A, B on q_proj/v_proj.
Operation
Use W + (α/r)BA. After trainer.train(), verify a nonzero adapter change and save adapter plus tokenizer.
Output
An adapter paired with a locked base model revision.
Why it matters
LoRA reduces trainable parameters, but base weights and activations still occupy memory.

Before: AdamW & LR Scheduler → After: B0/B1 Generation

PT09

B0/B1 Generation

B0 uses the base model; B1 loads the compatible adapter.

Input
The same frozen benchmark prompts and generation settings.
Operation
Use generate_items with greedy decoding and inference_mode; check adapter/base revisions. max_new_tokens limits new output.
Output
Candidate scripts and generation records; no generated code is executed.
Why it matters
Matched settings make the comparison interpretable; generating code does not validate it.

Before: LoRA Parameter Update & Adapter → After: Benchmark Evaluation

PT10

Benchmark Evaluation

Automatic layers and independent execution/review answer different questions.

Input
B0/B1 candidates on the same suite, rules and scorer version.
Operation
Evaluate L0 form, L1 framework, L2 grounding and L2.5 oracle. L3 execution and L4 review are separate. Compare matched tasks.
Output
Layered evidence and paired changes, not a fabricated accuracy score.
Why it matters
Lower training loss alone does not establish useful or generalizable scripts.

Before: B0/B1 Generation → After: End of walkthrough

POST-TRAINING / PARAMETER LAB

Parameter laboratory

Deterministic teaching calculations; no model training or project config changes. N=56, matrix dimensions and token counts are assumptions. Results are not measured loss, accuracy, runtime or memory.

The 30/112 buttons change max_steps and bring an out-of-budget cursor or warmup back into range; other choices remain unchanged.

Effective batch1
Exposures30
Approx. epochs0.5357
LR5.0000e-5
LoRA parameters16,384
LoRA scale2
Training tokens1,280
Generation budget3,072

Training length check: Pass · Detailed formulas and curves ↓

Update budget: step / batch / epoch
Definition, config and conditions

Number of valid training samples, not raw JSONL lines.

Template / default
56 is a teaching assumption; the repository has no default N
Project location
train.py: length of encoded after split=train filtering
Exploration range and conditions
Try 28/40/56/112 for small-data scenarios; UI bounds are 1–1,000,000.
Relationships
epochs ≈ steps × effective batch / N; smaller N repeats samples more often.
Typical risks
Larger N in this calculator creates no diversity; small pools may be memorized and need independent evaluation.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT01

Definition, config and conditions

Samples processed by one process in a forward/backward pass.

Template / default
The project hard-codes 1
Project location
train.py · per_device_train_batch_size
Exploration range and conditions
Teaching range 1–32; confirm RAM before increasing the actual CPU setting of 1.
Relationships
Multiplies with accumulation and processes to form effective batch.
Typical risks
Large batches increase activation memory; small batches can have noisier gradients.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT06

Definition, config and conditions

Micro-batches accumulated before one optimizer update.

Template / default
cpu-long template: 1
Project location
configs/cpu-long.json · gradient_accumulation_steps
Exploration range and conditions
Start with 1/2/4/8 and compare exposure budgets; teaching cap 128.
Relationships
At fixed steps, more accumulation increases exposures; equal exposure does not imply equal optimization.
Typical risks
Large values delay updates and may reduce their count for a fixed budget; small values do not guarantee stability.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT06

Definition, config and conditions

Data-parallel training processes, not CPU threads.

Template / default
Current single CPU process: 1
Project location
Runtime topology; not cpu-long threads
Exploration range and conditions
1 matches this project; 2/4/8 are hypothetical distributed comparisons, capped at 16.
Relationships
Contributes to B_eff; distributed sampler padding can change actual exposure.
Typical risks
More processes need distributed support and resources; this field deploys nothing and communication has a cost.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT06

Definition, config and conditions

Optimizer update budget, not the number of micro-batches.

Template / default
cpu-long template: 30; 112 is a teaching comparison
Project location
configs/cpu-long.json · max_steps; CLI --max-steps can override
Exploration range and conditions
Compare 30 and 112; plan using N, desired epochs and batch, with a UI cap of 100,000.
Relationships
Changes both exposure budget and linear LR decay progress.
Typical risks
Too few updates may underfit; too many may memorize. Improvement is not monotonic.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT07

Linear learning-rate plan
Definition, config and conditions

Peak/base update scale of the linear schedule.

Template / default
cpu-long template: 1e-4
Project location
configs/cpu-long.json · learning_rate
Exploration range and conditions
Compare 5e-5/1e-4/2e-4 for LoRA; 0–0.01 are demo input bounds, not recommendations.
Relationships
Interacts with the scheduler, batch and α/r.
Typical risks
Too large may destabilize; too small updates slowly; 0 disables LR-driven updates.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT07

Definition, config and conditions

Updates used to increase LR linearly from zero to η₀.

Template / default
Not explicitly configured; Transformers 4.57.1 default: 0
Project location
train.py omits warmup in TrainingArguments; changing training would require a separate code/config change
Exploration range and conditions
Current value is 0; compare with a few warmup steps, requiring 0 ≤ warmup < max_steps.
Relationships
Consumes part of the total budget and changes the remaining decay interval.
Typical risks
Too long keeps short runs at low LR; 0 is not a universal recommendation.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT07

Definition, config and conditions

Position after this many optimizer updates.

Template / default
15 is the inspection cursor default, not a training setting
Project location
Teaching cursor; real logs use Trainer global_step
Exploration range and conditions
0–max_steps; 0 is initial state and LR is zero after the final step.
Relationships
Moving the cursor inspects the plan without changing total exposures.
Typical risks
The cursor is not evidence of a completed run; verify the timing of real log entries.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT07

Single-layer LoRA math
Definition, config and conditions

Rows of A and columns of B, bounding the rank of the update.

Template / default
cpu-long template: 8
Project location
configs/cpu-long.json · lora_r
Exploration range and conditions
Compare 4/8/16/32 one at a time; demo cap 256 and no larger than either dimension.
Relationships
P=r(d_in+d_out); at fixed α, increasing r reduces α/r.
Typical risks
Larger ranks add capacity and parameters without guaranteeing quality; smaller ranks may restrict expressiveness.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT08

Definition, config and conditions

Numerator of standard LoRA scaling; this project does not enable rsLoRA.

Template / default
cpu-long template: 16
Project location
configs/cpu-long.json · lora_alpha
Exploration range and conditions
At fixed r compare α=r and 2r; demo bounds are 0–1024.
Relationships
scale=α/r; alpha does not change parameter count.
Typical risks
Large scales may destabilize; α=0 disables the update, not the resource cost.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT08

Definition, config and conditions

Input vector width of one linear layer.

Template / default
1024 is a math example, not a Qwen layer shape
Project location
Teaching-only input; inspect actual model layers for real dimensions
Exploration range and conditions
Compare hypothetical widths 128–4096; input bounds are 1–16384.
Relationships
A ∈ R^(r×d_in), W ∈ R^(d_out×d_in).
Typical risks
Larger widths add parameters and compute; never multiply by guessed layer counts to claim a model total.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT08

Definition, config and conditions

Output vector width of one linear layer.

Template / default
1024 is a math example, not a Qwen layer shape
Project location
Teaching-only input; inspect actual model layers for real dimensions
Exploration range and conditions
Compare hypothetical widths 128–4096; input bounds are 1–16384.
Relationships
B ∈ R^(d_out×r); BA has the same shape as W.
Typical risks
Dimensions define the hypothetical layer; base weights and activations remain, so peak memory cannot be inferred.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT08

Training and generation token budgets
Definition, config and conditions

Prompt prefix length after the chat template, including formatting tokens.

Template / default
1024 is a synthetic count, not a tokenizer measurement
Project location
common.py · len(prompt) in encode_sample
Exploration range and conditions
Use a real token audit in practice; 1–32768 here is for boundary demonstrations.
Relationships
Participates in forward with labels=-100; generation uses this prompt prefix too.
Typical risks
Long prompts cost context and compute; short prompts missing facts cannot be repaired by assuming training knows them.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT04

Definition, config and conditions

Assistant target suffix length contributing directly to token loss.

Template / default
256 is a synthetic count
Project location
common.py · full[len(prompt):]
Exploration range and conditions
Measure real encoded targets; demo range 1–32768, with zero supervision rejected.
Relationships
Training length=prompt+supervised; this is distinct from max_new_tokens.
Typical risks
Long targets add training cost; missing or overly short targets cannot provide complete supervision.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT04

Definition, config and conditions

Full training sequence cap; this project also checks generation prompt length against it.

Template / default
cpu-long template: 8192
Project location
configs/cpu-long.json · max_length
Exploration range and conditions
Audit lengths before trying 2048/4096/8192; UI cap 32768 does not guarantee model support.
Relationships
Overlong prompt+target is rejected, never silently truncated; this is not a fixed padding length.
Typical risks
Too small rejects samples; too large permits expensive sequences but does not lengthen actual samples.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT04

Definition, config and conditions

Maximum newly generated tokens; EOS may stop generation earlier.

Template / default
Benchmark CLI default 2048; quick generate.py default 256
Project location
scripts/bench/run_generate.py · --max-new-tokens
Exploration range and conditions
Audit output lengths and compare 256/1024/2048; demo cap 32768 still requires model context support.
Relationships
Generation budget upper bound=prompt+max_new_tokens; training cap is unchanged.
Typical risks
Too small may truncate code; larger budgets guarantee neither correctness nor that generation reaches the limit.

Pinned source / basis ↗ · Parameter reference ↗ · Calculations and experiments ↗ · Related module PT09

Bounds: finite numbers, integer counts, warmup < max_steps, current step ≤ max_steps and r ≤ min(d_in,d_out). An overlong training sequence is shown as a rejection example.

Sample exposure plan

B_eff = b × g × w = 1

exposures ≈ S × B_eff = 30

epochs ≈ exposures / N = 0.5357

This plans full batches approximately. Partial final batches, accumulation across epochs and distributed sampler padding can change actual exposures; this is not a per-sample run log.

LoRA: one hypothetical linear layer

ΔW = (α/r)BA · scale = α/r = 2

P = r(d_in + d_out) = 16,384 parameters

W: d_out × d_in = 1,048,576 · 1.5625%

A: 8 × 1024; B: 1024 × 8; BA: 1024 × 1024

The percentage compares this layer's adapter and full matrix, not whole-model savings. Base weights and activations still occupy memory; larger rank does not guarantee better independent evaluation.

Learning-rate curve, not training loss

η(s) = η₀·s/W (s < W); then η₀·max(0, (S−s)/(S−W))

LR after current update: 5.0000e-5

1.0e-400112

Solid: selected plan; dashed: 30 steps / warmup=0; dotted: 112 steps / warmup=0. All use the same η₀ and update-count x axis. Matching plans overlap; zero extensions beyond each budget aid comparison and do not imply continued training.

Changing max_steps also changes decay progress at the same update count. These curves are formulas, not logs; the cursor denotes completed updates.

Training labels and generation budget

Bar left: prompt (label=-100); right: supervised suffix. Lengths are synthetic counts, not real tokenization.

Training sequence length: 1,280 · Passes length check

Generation prompt check: Passes · Prompt + new-token budget upper bound: 3,072

Overlong training samples are rejected, not truncated. Prompt tokens still participate in forward but not directly in loss. Generation also depends on EOS and actual model context limits; output need not reach max_new_tokens.