Skip to content

Make ControlVector.train() deterministic (fix unseeded PCA solver)#79

Open
bamdadd wants to merge 1 commit into
vgel:mainfrom
bamdadd:fix-pca-nondeterminism
Open

Make ControlVector.train() deterministic (fix unseeded PCA solver)#79
bamdadd wants to merge 1 commit into
vgel:mainfrom
bamdadd:fix-pca-nondeterminism

Conversation

@bamdadd

@bamdadd bamdadd commented Jul 13, 2026

Copy link
Copy Markdown

Fixes #78.

read_representations fits PCA(n_components=1) with the default svd_solver="auto". For transformer hidden-state widths (n_features > 500) sklearn's auto heuristic selects the randomized SVD solver, which is unseeded (random_state=None), so ControlVector.train() returns a different vector each run for identical inputs. On weak-signal concepts the direction diverges materially (cosine 0.5–0.9 between runs on the same data); on well-separated concepts the direction is stable but still not bit-identical.

svd_solver="full" is exact and deterministic, and is negligibly priced for n_components=1. One line, no API change.

Repro (numpy + scikit-learn only, no model/GPU) and full analysis are in the issue. If you'd prefer to keep the randomized solver's speed for very large datasets, I'm happy to instead thread an optional random_state through trainread_representationsPCA(...) — just say which you prefer.

read_representations fits PCA(n_components=1) with the default svd_solver='auto',
which selects the randomized SVD solver for hidden-state widths (>500 features).
That solver is unseeded (random_state=None), so identical inputs produce
different directions across runs. svd_solver='full' is exact and deterministic,
and negligibly priced at n_components=1.

Fixes vgel#78
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ControlVector.train() is non-deterministic: PCA svd_solver="auto" selects an unseeded randomized SVD

1 participant