Limitations
What Gradian will not do, and the constraints that decide whether it fits your setup at all.
Some of these decide whether Gradian fits your setup at all, so it is worth checking against your setup before you invest time in a fine-tune, whichever point in these docs you found this page from.
What Gradian will not analyze#
LoRA adapters only. Attribution differentiates with respect to adapter parameters, so a full
fine-tune has nothing to attribute over and gradian attribute exits rather than guess. The hook path
covers LoRA on the Linear layers of a HuggingFace causal LM. LoRA on embeddings or convolutions is
skipped, so an adapter that lives only there produces no blocks to index.
Causal language models only. Models are loaded as AutoModelForCausalLM with a CAUSAL_LM PEFT
task type. Sequence classification and encoder-decoder adapters are not supported.
A 4-bit adapter is analyzed against an unquantized base. The attribution loader has no quantization path, so a QLoRA fine-tune indexes at full precision. That costs memory, and it moves the loss slightly relative to how the adapter was trained.
A base model without a chat template degrades quietly. Supervision falls back to the whole
sequence rather than the assistant turn. The data.no_chat_template check catches this, which is one
reason to run gradian diagnose first.
Scale and hardware#
One device, one process. No device_map, no DDP or FSDP, no sharding. The device is CUDA or CPU,
chosen automatically. MPS works if you set it explicitly and is never auto-selected. Windows needs
WSL2, and Intel Macs are not supported.
The gradient index is big. It holds one vector per training example.
| Model | LoRA r=16, all 7 sites | Per example | 2000 examples |
|---|---|---|---|
| 1B | about 11M params | about 45 MB | about 90 GB |
| 8B | about 42M params | about 170 MB | about 340 GB |
Three settings shrink the stored index: grads.module_filter cuts it about 4.3x, measured, by
indexing one module type (down_proj) instead of seven -- it is the largest single site, not an
equal 1/7th share, so the saving is smaller than a naive 7x -- grads.storage_dtype: float16
halves it, and grads.projection_dim makes it
independent of model size at a measured cost in ranking fidelity, with Spearman against exact scores
falling to roughly 0.6 to 0.9 depending on the width you pick.
Peak GPU memory is the logit upcast, not the index. The allocation that actually fails is
grads.batch_size x supervised_tokens x vocab x 4 bytes, from the fp32 upcast of the logits. Only
the positions the loss is computed on reach that upcast, so prompt tokens and padding are free, but
a batch with long answers costs more than a batch of the same length with short ones. With a
128k-vocab Llama-3 tokenizer at batch 8 and 512 supervised tokens that single tensor is about 2.1 GB
on top of the fp16 logits it came from. It exists because Gradian computes its own loss from logits
instead of passing labels=, which is what keeps fused cross-entropy kernels from swallowing the
gradients it captures, so it is a deliberate cost rather than a leak.
Only grads.batch_size and grads.max_seq_length reduce it. The three index-shrinking settings above
will not rescue an out-of-memory error at this line. Measured: a 16GB V100 runs out of memory on a 1B
model at a gradient batch of 8, and runs clean at 2.
Inputs#
Datasets are local. A .jsonl file, a .json file, or a directory written by HuggingFace
save_to_disk. Hub dataset ids are not resolved for you.
Dataset order matters. Example ids embed position, and the index cache key derives from them, so a reordered file is a different dataset as far as the cache is concerned.
Without an eval set you get a smoke test. Attribution falls back to scoring against the first few
training examples and flags attribution.no_capability_target. It runs, but it is not a diagnosis.
Method#
Influence is a first-order approximation, not a proof. A score predicts what removing an example would do to the loss. The only thing that demonstrates it is dropping the accused examples and retraining.
Plenty of honest runs end without a verdict. If the capability delta's bootstrap confidence
interval includes zero, Gradian reports the delta and explicitly declines to attribute. Small eval sets
land there often. This is deliberate, and turning off evaluation.require_significant removes the main
guard against reading noise as a result.
The capability metric is load-bearing. A log-likelihood metric can go up even under a successful
poisoning, because a fine-tune mostly teaches answer format. It also produces no generated text for the
contrastive query to subtract, so it silently falls back to the classic formulation, which inverts the
sign on substitution failures. Use exact_match or contains for factual capabilities.
A single error buried in a long document can sit below the noise floor. Dilution is roughly 760x against a short entry stating the same thing. Cluster aggregation recovers it when several examples share the problem, and span-level drill-down localizes it 92% of the time, but only when the query is built from the single failing item.
Assumes a converged optimum. Influence functions are defined at a minimum. Mid-schedule checkpoints give noisier rankings.
The base model stays opaque. Gradian runs the base model and bounds blame with base scores and preference margins, but it never sees the base model's training data and makes no claim about it.
Determinism is best-effort on GPU. Deterministic algorithms are requested with warn_only, so a
non-deterministic kernel warns rather than fails. Reruns are bit-identical on CPU, and in practice
stable on GPU, but the guarantee is not absolute.
Project status#
Alpha. Version 0.1.0, classified as Development Status :: 3 - Alpha, installed from the script
or a checkout. There is no package-index release, so installing needs access to the repository.
The unsloth training backend is verified at contract level on CPU only. End-to-end parity between
the HF and unsloth backends is GPU-gated and has no recorded pass yet. This affects gradian train --backend unsloth, not analysis of a model you trained with unsloth yourself.
The repository README has a "What is next" section covering the work that addresses several of these, including the EK-FAC cross-check engine and leave-one-out fidelity correlation.