Download workspace/cil/chart_features.py from anhtld/vla: direct link, hf CLI and curl.
- Browser
- Download file 4.35 kB
-
https://huggingface.co/anhtld/vla/resolve/main/workspace/cil/chart_features.py
- Command line
-
hf download hf://anhtld/vla/workspace/cil/chart_features.py
-
curl -L -o chart_features.py https://huggingface.co/anhtld/vla/resolve/main/workspace/cil/chart_features.py
4.35 kB
| from __future__ import annotations | |
| import hashlib | |
| from pathlib import Path | |
| from typing import Any | |
| try: | |
| import numpy as np | |
| except ImportError: # pragma: no cover | |
| np = None | |
| CONTEXT_HASH_WIDTH = 8 | |
| OBSERVATION_EMBED_DIM = 32 | |
| OBJECT_LAYOUT_EMBED_DIM = 64 | |
| CHART_FEATURE_MODES = ( | |
| "base", | |
| "base_context", | |
| "base_context_obs", | |
| "base_context_obj", | |
| "base_context_obs_obj", | |
| ) | |
| _EMBEDDING_CACHE: dict[str, Any] = {} | |
| def build_chart_feature( | |
| base_action: Any, | |
| metadata: dict[str, Any] | None = None, | |
| *, | |
| mode: str = "base", | |
| ) -> Any: | |
| """Build a deployment-visible chart feature vector. | |
| `base` preserves the original behavior: the chart token is the flattened | |
| base action chunk. `base_context` appends stable hashes of task/language | |
| metadata that are visible at proposal time. `base_context_obs` additionally | |
| appends a precomputed observation embedding referenced by metadata. | |
| `base_context_obj` appends a precomputed RGB object-layout embedding, and | |
| `base_context_obs_obj` appends both. These modes intentionally do not read | |
| outcomes, labels, hidden chart branches, or evaluator-only fields. | |
| """ | |
| if np is None: # pragma: no cover | |
| raise ImportError("build_chart_feature requires numpy") | |
| if mode not in CHART_FEATURE_MODES: | |
| raise ValueError(f"unknown chart feature mode: {mode}") | |
| base = np.asarray(base_action, dtype=np.float32).reshape(-1) | |
| if mode == "base": | |
| return base | |
| metadata = metadata or {} | |
| context = np.asarray( | |
| [ | |
| *_stable_hash_features(str(metadata.get("task_id", "")), CONTEXT_HASH_WIDTH), | |
| *_stable_hash_features(str(metadata.get("instruction", "")).lower(), CONTEXT_HASH_WIDTH), | |
| min(len(str(metadata.get("instruction", ""))) / 128.0, 4.0), | |
| min(len(str(metadata.get("instruction", "")).split()) / 32.0, 4.0), | |
| ], | |
| dtype=np.float32, | |
| ) | |
| if mode in {"base_context_obs", "base_context_obs_obj"}: | |
| obs = _load_embedding( | |
| metadata.get("observation_embedding_path"), | |
| dim=OBSERVATION_EMBED_DIM, | |
| chart_root=metadata.get("_chart_root"), | |
| ) | |
| context = np.concatenate([context, obs.astype(np.float32, copy=False)]) | |
| if mode in {"base_context_obj", "base_context_obs_obj"}: | |
| obj = _load_embedding( | |
| metadata.get("object_embedding_path"), | |
| dim=OBJECT_LAYOUT_EMBED_DIM, | |
| chart_root=metadata.get("_chart_root"), | |
| ) | |
| context = np.concatenate([context, obj.astype(np.float32, copy=False)]) | |
| return np.concatenate([base, context]).astype(np.float32, copy=False) | |
| def chart_feature_dim(base_action: Any, *, mode: str = "base") -> int: | |
| return int(build_chart_feature(base_action, {}, mode=mode).reshape(-1).shape[0]) | |
| def _stable_hash_features(text: str, width: int) -> list[float]: | |
| digest = hashlib.sha256(text.encode("utf-8")).digest() | |
| return [float(digest[index] / 127.5 - 1.0) for index in range(width)] | |
| def _load_embedding(value: Any, *, dim: int, chart_root: Any = None) -> Any: | |
| if np is None: # pragma: no cover | |
| raise ImportError("build_chart_feature requires numpy") | |
| if not value: | |
| return np.zeros(dim, dtype=np.float32) | |
| path_text, dataset, row_index = _parse_embedding_ref(str(value)) | |
| path = Path(path_text) | |
| if not path.is_absolute() and chart_root: | |
| path = Path(str(chart_root)) / path | |
| cache_key = str(path.resolve()) | |
| if cache_key not in _EMBEDDING_CACHE: | |
| with np.load(path, allow_pickle=False) as data: | |
| _EMBEDDING_CACHE[cache_key] = np.asarray(data[dataset], dtype=np.float32) | |
| matrix = _EMBEDDING_CACHE[cache_key] | |
| vector = np.asarray(matrix[int(row_index)], dtype=np.float32).reshape(-1) | |
| if vector.shape[0] == dim: | |
| return vector | |
| output = np.zeros(dim, dtype=np.float32) | |
| width = min(dim, vector.shape[0]) | |
| output[:width] = vector[:width] | |
| return output | |
| def _parse_embedding_ref(value: str) -> tuple[str, str, int]: | |
| if "#" not in value: | |
| return value, "embeddings", 0 | |
| path_text, ref = value.split("#", 1) | |
| parts = [part for part in ref.split("/") if part] | |
| if len(parts) != 2: | |
| raise ValueError(f"invalid observation embedding ref: {value}") | |
| return path_text, parts[0], int(parts[1]) | |