Add vocab sphere with attn layers - #867
Open
klei22 wants to merge 2 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends the hf-vocab-sphere tool with model-aware vector arithmetic (attention/MLP helper functions and norm helpers), adds vector “participation ratio”/effective-dimension metadata to projection points, and updates the frontend to expose these new controls and label components.
Changes:
- Expanded
vector_math’s safe expression evaluator to support model-dispatched functions (norm,invnorm,wqk/wkq,attn_layer,mlp_layer, etc.) and finite SLERP extrapolation. - Added effective-dimension metrics to API schemas and projection responses, and surfaced them in the UI as optional label components + hotkeys.
- Implemented auxiliary tensor loading/caching to support attention/MLP computations from safetensors.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| report/threejs/hf-vocab-sphere/tests/test_vector_math.py | Adds coverage for nested model functions, SLERP extrapolation, and effective-dimension metrics. |
| report/threejs/hf-vocab-sphere/tests/test_frontend_contract.py | Extends contract checks for new UI controls, settings keys, and hotkeys. |
| report/threejs/hf-vocab-sphere/app/vector_math.py | Adds vector metrics + model-function dispatch support to the safe evaluator. |
| report/threejs/hf-vocab-sphere/app/templates/index.html | Adds UI controls for layer-helper insertion, SLERP extrapolation input, and label toggles. |
| report/threejs/hf-vocab-sphere/app/static/app.js | Implements new label components, hotkeys, settings wiring, and expression insertion helpers. |
| report/threejs/hf-vocab-sphere/app/schemas.py | Extends API models with effective-dimension fields. |
| report/threejs/hf-vocab-sphere/app/model_store.py | Adds safetensors scanning/caching and model-vector helper implementations for attention/MLP ops. |
| report/threejs/hf-vocab-sphere/app/main.py | Wires model-function dispatch into arithmetic evaluation and adds effective-dimension metrics to points. |
Comments suppressed due to low confidence (4)
report/threejs/hf-vocab-sphere/app/vector_math.py:185
- String literals are now supported as function selectors, but unary +/- still blindly multiplies
operand.valueby a float. For expressions like-'attn'this will raise aTypeErrorinstead of a controlledValueError(and can surface as a 500). Reject unary operators forstringvalues explicitly.
if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)):
operand = self._visit(node.operand)
sign = 1.0 if isinstance(node.op, ast.UAdd) else -1.0
return _Value(operand.kind, operand.value * sign)
report/threejs/hf-vocab-sphere/app/model_store.py:1036
- Cache population for
_AUX_TENSOR_CACHEis also unsynchronized. Even with a locked read, writes should be guarded too to keep cache state consistent and make behavior predictable under concurrency.
handle.get_tensor(str(name)).detach().cpu().to(dtype=torch.float32).contiguous()
)
_AUX_TENSOR_CACHE[cache_key] = tensors
return tensors
report/threejs/hf-vocab-sphere/app/vector_math.py:180
- String literals should only be usable as selectors inside model-function calls (e.g.
norm(A, 0, 'attn', 'input')). As written, a string literal can appear anywhere in an expression and later hit arithmetic nodes, causingTypeError. Gate string-literal parsing behind an internal flag that is only enabled while visiting model-function arguments.
if isinstance(node, ast.Constant) and isinstance(node.value, str):
text = node.value.strip().casefold()
if not text or len(text) > 40:
raise ValueError("String arguments must be short, non-blank selectors.")
return _Value("string", text)
report/threejs/hf-vocab-sphere/app/vector_math.py:213
- After restricting string literals to model-function argument lists, the model-function argument evaluation needs to temporarily allow strings while visiting
node.args, then disable it again so strings cannot escape into the surrounding expression.
if function_name in {"norm", "invnorm", "inverse_norm", "wov", "wqk", "wkq", "attn_layer", "mlp_layer"}:
if self.model_function is None:
raise ValueError(f"{node.func.id} requires model auxiliary tensors loaded by the projection API.")
values = [self._visit(argument) for argument in node.args]
args: list[float | str | np.ndarray] = [
np.asarray(value.value)
if value.kind == "vector"
else (str(value.value) if value.kind == "string" else float(value.value))
for value in values
]
return _Value("vector", self.model_function(function_name, args))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+988
to
+995
| _AUX_TENSOR_CACHE: dict[tuple[str, str, bool], dict[str, torch.Tensor]] = {} | ||
|
|
||
|
|
||
| def _all_safetensor_tensors(model_name: str, *, revision: str, allow_download: bool = True) -> dict[str, torch.Tensor]: | ||
| cache_key = (model_name, revision, allow_download) | ||
| cached = _AUX_TENSOR_CACHE.get(cache_key) | ||
| if cached is not None: | ||
| return cached |
Comment on lines
+1336
to
+1338
| def model_vector_function(assets: ModelAssets, name: str, args: list[float | str | np.ndarray]) -> np.ndarray: | ||
| tensors = _all_safetensor_tensors(assets.model_name, revision=assets.revision, allow_download=True) | ||
| if name in {"norm", "invnorm", "inverse_norm"}: |
Comment on lines
134
to
136
| self.aliases = {name.upper(): np.asarray(vector, dtype=np.float64) for name, vector in aliases.items()} | ||
| self.model_function = model_function | ||
| self.referenced: set[str] = set() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.