chore: import upstream snapshot with attribution
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:28:05 +08:00
commit 41cb1c0170
1830 changed files with 38276124 additions and 0 deletions
+528
View File
@@ -0,0 +1,528 @@
#!/usr/bin/env python3
"""
Extract token embeddings from nomic-embed-code (7B) for static lookup table.
Loads the full model, filters the vocabulary to code-relevant tokens,
runs full inference on each token, applies simulated attention, quantizes
to int8, and outputs files compatible with vendored/unixcoder/ format.
Usage:
pip3.9 install torch transformers sentence-transformers
python3.9 scripts/extract_nomic_vectors.py [--output-dir vendored/nomic]
Output:
code_vectors.bin — [int32 count][int32 dim] + count×dim int8
code_tokens.txt — one token per line
code_tokens.h — C header: static const char *PRETRAINED_TOKENS[N]
code_vectors.h — C header: defines + inline accessor
code_vectors_blob.S — assembler .incbin
One-time extraction. ~2-3h on GPU, ~6-10h on M3 Pro CPU (float16, ~14GB RAM).
"""
import argparse
import json
import os
import re
import struct
import sys
import time
from pathlib import Path
import numpy as np
import torch
# Parallelize CPU inference across all cores BEFORE any torch ops
NUM_THREADS = min(os.cpu_count() * 2, 12)
torch.set_num_threads(NUM_THREADS)
torch.set_num_interop_threads(max(NUM_THREADS // 2, 1))
os.environ.setdefault("OMP_NUM_THREADS", str(NUM_THREADS))
os.environ.setdefault("MKL_NUM_THREADS", str(NUM_THREADS))
from transformers import AutoModel, AutoTokenizer
# ── Configuration ──────────────────────────────────────────────────────
MODEL_NAME = "nomic-ai/nomic-embed-code"
OUTPUT_DIM = 768 # Target dimension (Matryoshka truncation if model outputs more)
SIM_ATTENTION_K = 32 # Top-K neighbors for simulated attention
SIM_ATTENTION_ITERS = 3 # Number of simulated attention iterations
SIM_ATTENTION_ALPHA = 0.3 # Blend ratio: (1-α)×original + α×neighbor_mean
BATCH_SIZE = 32 # Tokens per inference batch (sized for thread saturation)
CHECKPOINT_EVERY = 500 # Save checkpoint every N tokens
# ── Token filtering ───────────────────────────────────────────────────
def is_code_relevant(token_str: str) -> bool:
"""Filter vocabulary to code-relevant tokens.
Goal: keep tokens that our runtime camelCase/snake_case splitter would
produce from identifiers. Reject BPE noise, punctuation combos, and
non-Latin scripts.
"""
s = token_str.strip()
if not s:
return False
# Remove BPE markers (Ġ = space prefix, ▁ = sentencepiece, Ċ/ċ = newline in Qwen)
clean = s.lstrip("\u0120\u2581") # Ġ, ▁
if not clean:
return False
# Skip special tokens
if clean.startswith("<") and clean.endswith(">"):
return False
if clean.startswith("[") and clean.endswith("]"):
return False
# Strip leading/trailing underscores (common in BPE) but keep content
inner = clean.strip("_")
if not inner:
return False
# STRICT: must be purely alphanumeric + underscores (identifier-shaped)
# This rejects BPE noise like "!");ċ", "!!!!ċċ", etc.
if not re.match(r'^[a-zA-Z][a-zA-Z0-9_]*$', inner):
return False
# Must be at least 2 chars of actual content
if len(inner) < 2:
return False
return True
def clean_token(token_str: str) -> str:
"""Normalize a BPE token to the form our runtime tokenizer produces."""
s = token_str.strip()
# Strip BPE space markers
s = s.lstrip("\u0120\u2581")
# Strip leading/trailing underscores
s = s.strip("_")
# Lowercase (our runtime tokenizer lowercases)
s = s.lower()
return s
# ── Simulated attention ──────────────────────────────────────────────
def simulated_attention(vectors: np.ndarray, k: int, iterations: int,
alpha: float) -> np.ndarray:
"""
Apply simulated self-attention: for each vector, blend with mean of
top-K nearest neighbors. This approximates contextual composition
that real attention provides.
vectors: (N, D) float32 unit-normalized
Returns: (N, D) float32 unit-normalized
"""
n, d = vectors.shape
result = vectors.copy()
for iteration in range(iterations):
t0 = time.time()
# Compute cosine similarity matrix in chunks to avoid OOM
# For 40K vectors × 768d, full matrix = 40K² × 4 bytes = 6.4GB
# Process in chunks of 2048
chunk_size = 2048
new_result = np.zeros_like(result)
for i in range(0, n, chunk_size):
end = min(i + chunk_size, n)
chunk = result[i:end] # (chunk, D)
# Cosine similarity: chunk × all^T
sims = chunk @ result.T # (chunk, N)
# For each vector in chunk, find top-K neighbors (excluding self)
for j in range(end - i):
global_idx = i + j
sim_row = sims[j].copy()
sim_row[global_idx] = -1.0 # Exclude self
# Top-K indices
if k < n - 1:
top_k_idx = np.argpartition(sim_row, -k)[-k:]
else:
top_k_idx = np.arange(n)
top_k_idx = top_k_idx[top_k_idx != global_idx]
neighbor_mean = result[top_k_idx].mean(axis=0)
# Blend
blended = (1 - alpha) * result[global_idx] + alpha * neighbor_mean
# Re-normalize
norm = np.linalg.norm(blended)
if norm > 1e-8:
blended /= norm
new_result[global_idx] = blended
result = new_result
elapsed = time.time() - t0
print(f" sim-attention iter {iteration + 1}/{iterations}: {elapsed:.1f}s")
return result
# ── Extraction ───────────────────────────────────────────────────────
def extract_embeddings(model, tokenizer, tokens: list, device: str,
batch_size: int = 64,
checkpoint_path: str = None) -> np.ndarray:
"""Run full model inference on each token string. Returns (N, D) float32."""
# Check for checkpoint
start_idx = 0
all_vecs = []
if checkpoint_path and os.path.exists(checkpoint_path):
data = np.load(checkpoint_path)
all_vecs = list(data["vectors"])
start_idx = len(all_vecs)
print(f" resuming from checkpoint: {start_idx}/{len(tokens)} tokens")
model.eval()
total = len(tokens)
t0 = time.time()
with torch.no_grad():
for batch_start in range(start_idx, total, batch_size):
batch_end = min(batch_start + batch_size, total)
batch_tokens = tokens[batch_start:batch_end]
# nomic-embed-code requires search_query or search_document prefix
# For single tokens, we use the token as-is (query mode)
texts = [f"search_query: {t}" for t in batch_tokens]
encoded = tokenizer(
texts,
padding=True,
truncation=True,
max_length=64,
return_tensors="pt"
).to(device)
outputs = model(**encoded)
# Mean pooling over non-padding tokens
attention_mask = encoded["attention_mask"]
token_embeddings = outputs.last_hidden_state
input_mask_expanded = (
attention_mask.unsqueeze(-1)
.expand(token_embeddings.size())
.float()
)
sum_embeddings = torch.sum(
token_embeddings * input_mask_expanded, dim=1
)
sum_mask = torch.clamp(input_mask_expanded.sum(dim=1), min=1e-9)
mean_pooled = sum_embeddings / sum_mask
# Truncate to OUTPUT_DIM if model outputs more (Matryoshka)
if mean_pooled.shape[1] > OUTPUT_DIM:
mean_pooled = mean_pooled[:, :OUTPUT_DIM]
# L2 normalize
mean_pooled = torch.nn.functional.normalize(mean_pooled, p=2, dim=1)
vecs = mean_pooled.cpu().numpy()
all_vecs.extend(vecs)
# Progress
done = batch_end
elapsed = time.time() - t0
rate = (done - start_idx) / elapsed if elapsed > 0 else 0
eta = (total - done) / rate if rate > 0 else 0
print(
f" [{done:>6}/{total}] "
f"{rate:.1f} tok/s "
f"ETA {eta / 60:.0f}m",
flush=True
)
# Checkpoint
if checkpoint_path and (done % CHECKPOINT_EVERY < batch_size):
np.savez_compressed(
checkpoint_path,
vectors=np.array(all_vecs, dtype=np.float32)
)
print()
return np.array(all_vecs, dtype=np.float32)
# ── Output generation ────────────────────────────────────────────────
def write_bin(path: str, vectors: np.ndarray, dim: int):
"""Write binary blob: [int32 count][int32 dim] + count×dim int8."""
n = vectors.shape[0]
# Quantize: scale to [-127, 127], round to int8
quantized = np.clip(np.round(vectors * 127.0), -127, 127).astype(np.int8)
with open(path, "wb") as f:
f.write(struct.pack("<ii", n, dim))
f.write(quantized.tobytes())
size_mb = os.path.getsize(path) / (1024 * 1024)
print(f" {path}: {n} vectors × {dim}d = {size_mb:.1f} MB")
def write_tokens_txt(path: str, tokens: list):
"""Write plain text token list."""
with open(path, "w") as f:
for t in tokens:
f.write(t + "\n")
print(f" {path}: {len(tokens)} tokens")
def write_tokens_h(path: str, tokens: list):
"""Write C header with token string array."""
with open(path, "w") as f:
f.write(f"/* nomic-embed-code token vocabulary — {len(tokens)} tokens. */\n")
f.write("#ifndef CBM_NOMIC_TOKENS_H\n")
f.write("#define CBM_NOMIC_TOKENS_H\n\n")
f.write(f"static const char *PRETRAINED_TOKENS[{len(tokens)}] = {{\n")
for t in tokens:
escaped = t.replace("\\", "\\\\").replace('"', '\\"')
f.write(f'"{escaped}",\n')
f.write("};\n\n")
f.write("#endif /* CBM_NOMIC_TOKENS_H */\n")
print(f" {path}: written")
def write_vectors_h(path: str, token_count: int, dim: int, incbin_path: str):
"""Write C header with defines and inline accessor."""
with open(path, "w") as f:
f.write(f"""/* nomic-embed-code (nomic-ai/nomic-embed-code) token embeddings.
* {token_count} tokens x {dim}d int8-quantized unit vectors.
* Distilled from 7B model via full inference on filtered vocabulary.
* Simulated attention: {SIM_ATTENTION_ITERS} iterations, K={SIM_ATTENTION_K}, alpha={SIM_ATTENTION_ALPHA}.
*
* Vector blob embedded via code_vectors_blob.S (assembler .incbin).
* Token strings are in this header as a static array.
*
* Source: https://huggingface.co/nomic-ai/nomic-embed-code
* License: Apache 2.0
*/
#ifndef CBM_NOMIC_VECTORS_H
#define CBM_NOMIC_VECTORS_H
#include <stdint.h>
#define PRETRAINED_TOKEN_COUNT {token_count}
#define PRETRAINED_DIM {dim}
/* Raw vector blob: first 8 bytes = [int32 count][int32 dim],
* then count x dim int8 values (unit-normalized, x127 scaled). */
extern const unsigned char PRETRAINED_VECTOR_BLOB[];
extern const unsigned int PRETRAINED_VECTOR_BLOB_LEN;
/* Access the int8 vector for token index i. */
static inline const int8_t *pretrained_vec_at(int i) {{
return (const int8_t *)(PRETRAINED_VECTOR_BLOB + 8 + (size_t)i * PRETRAINED_DIM);
}}
/* Token strings (separate header to keep this file clean). */
#include "code_tokens.h"
#endif /* CBM_NOMIC_VECTORS_H */
""")
print(f" {path}: written")
def write_blob_s(path: str, incbin_path: str):
"""Write assembler .incbin directive."""
with open(path, "w") as f:
f.write(f"""/* nomic-embed-code vector blob embedded via assembler. */
.section __DATA,__const
.globl _PRETRAINED_VECTOR_BLOB
.globl _PRETRAINED_VECTOR_BLOB_LEN
.p2align 4
_PRETRAINED_VECTOR_BLOB:
.incbin "{incbin_path}"
_PRETRAINED_VECTOR_BLOB_END:
.section __DATA,__const
.p2align 2
_PRETRAINED_VECTOR_BLOB_LEN:
.long _PRETRAINED_VECTOR_BLOB_END - _PRETRAINED_VECTOR_BLOB
""")
print(f" {path}: written")
# ── Main ─────────────────────────────────────────────────────────────
def main():
parser = argparse.ArgumentParser(description="Extract nomic-embed-code token embeddings")
parser.add_argument("--output-dir", default="vendored/nomic",
help="Output directory (default: vendored/nomic)")
parser.add_argument("--device", default=None,
help="Device: cuda, mps, cpu (auto-detected)")
parser.add_argument("--skip-attention", action="store_true",
help="Skip simulated attention (faster, lower quality)")
parser.add_argument("--batch-size", type=int, default=BATCH_SIZE,
help=f"Batch size (default: {BATCH_SIZE})")
parser.add_argument("--checkpoint", default=None,
help="Checkpoint file path (auto: <output-dir>/checkpoint.npz)")
args = parser.parse_args()
batch_size = args.batch_size
# Auto-detect device
# Prefer CPU for 7B models on Apple Silicon — MPS shares unified memory
# with the system and can cause OOM/crashes. CPU keeps allocation predictable.
# Use --device mps to override if you have enough headroom (32GB+).
if args.device:
device = args.device
elif torch.cuda.is_available():
device = "cuda"
else:
device = "cpu"
# Force line-buffered stdout so tee/log sees output immediately
sys.stdout.reconfigure(line_buffering=True)
print(f"device={device}")
print(f"threads={torch.get_num_threads()}")
print(f"model={MODEL_NAME}")
print(f"output_dim={OUTPUT_DIM}")
print()
# Create output dir
out_dir = Path(args.output_dir)
out_dir.mkdir(parents=True, exist_ok=True)
checkpoint_path = args.checkpoint or str(out_dir / "checkpoint.npz")
# ── Step 1: Load model + tokenizer ──
print("step 1: loading model + tokenizer...")
t0 = time.time()
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME, trust_remote_code=True)
model = AutoModel.from_pretrained(
MODEL_NAME,
trust_remote_code=True,
dtype=torch.float16, # 7B×2B = ~14GB (vs 28GB float32)
low_cpu_mem_usage=True, # Stream weights, no 2x peak during load
)
model = model.to(device)
print(f" loaded in {time.time() - t0:.1f}s")
print(f" hidden_size={model.config.hidden_size}")
print(f" vocab_size={tokenizer.vocab_size}")
print()
# ── Step 2: Filter vocabulary ──
print("step 2: filtering vocabulary to code-relevant tokens...")
vocab = tokenizer.get_vocab()
print(f" raw vocabulary: {len(vocab)} tokens")
# Filter and deduplicate
seen = set()
filtered_tokens = []
for tok_str, tok_id in sorted(vocab.items(), key=lambda x: x[1]):
if not is_code_relevant(tok_str):
continue
clean = clean_token(tok_str)
if not clean or clean in seen:
continue
if len(clean) < 2:
continue
seen.add(clean)
filtered_tokens.append(clean)
filtered_tokens.sort()
print(f" code-relevant (deduplicated): {len(filtered_tokens)} tokens")
# Show sample
sample = filtered_tokens[:20]
print(f" sample: {sample}")
print()
# ── Step 3: Extract embeddings (full inference) ──
print(f"step 3: extracting embeddings ({len(filtered_tokens)} tokens, batch_size={batch_size})...")
t0 = time.time()
vectors = extract_embeddings(
model, tokenizer, filtered_tokens, device,
batch_size=batch_size, checkpoint_path=checkpoint_path
)
elapsed = time.time() - t0
print(f" extracted {vectors.shape[0]} vectors × {vectors.shape[1]}d in {elapsed:.0f}s")
# Truncate to OUTPUT_DIM if needed
if vectors.shape[1] > OUTPUT_DIM:
print(f" truncating {vectors.shape[1]}d -> {OUTPUT_DIM}d (Matryoshka)")
vectors = vectors[:, :OUTPUT_DIM]
# Re-normalize after truncation
norms = np.linalg.norm(vectors, axis=1, keepdims=True)
norms = np.maximum(norms, 1e-8)
vectors = vectors / norms
print(f" final shape: {vectors.shape}")
# Mean-center to fix anisotropy (transformer embeddings cluster tightly,
# making all cosine similarities ~0.95+). Subtracting the corpus mean
# spreads vectors apart, making cosine discriminative.
mean_vec = vectors.mean(axis=0)
mean_norm = np.linalg.norm(mean_vec)
print(f" mean vector norm before centering: {mean_norm:.4f} (>0.5 = anisotropic)")
vectors = vectors - mean_vec
# Re-normalize after centering
norms = np.linalg.norm(vectors, axis=1, keepdims=True)
norms = np.maximum(norms, 1e-8)
vectors = vectors / norms
mean_after = np.linalg.norm(vectors.mean(axis=0))
print(f" mean vector norm after centering: {mean_after:.6f}")
print()
# ── Step 4: Simulated attention ──
if not args.skip_attention:
print(f"step 4: simulated attention (K={SIM_ATTENTION_K}, "
f"iters={SIM_ATTENTION_ITERS}, alpha={SIM_ATTENTION_ALPHA})...")
t0 = time.time()
vectors = simulated_attention(
vectors, SIM_ATTENTION_K, SIM_ATTENTION_ITERS, SIM_ATTENTION_ALPHA
)
print(f" completed in {time.time() - t0:.1f}s")
print()
else:
print("step 4: simulated attention SKIPPED")
print()
# ── Step 5: Write output files ──
print("step 5: writing output files...")
dim = vectors.shape[1]
write_bin(str(out_dir / "code_vectors.bin"), vectors, dim)
write_tokens_txt(str(out_dir / "code_tokens.txt"), filtered_tokens)
write_tokens_h(str(out_dir / "code_tokens.h"), filtered_tokens)
incbin_path = f"vendored/nomic/code_vectors.bin"
write_vectors_h(str(out_dir / "code_vectors.h"), len(filtered_tokens), dim, incbin_path)
write_blob_s(str(out_dir / "code_vectors_blob.S"), incbin_path)
print()
# Cleanup checkpoint
if os.path.exists(checkpoint_path):
os.remove(checkpoint_path)
print(f" removed checkpoint: {checkpoint_path}")
# ── Summary ──
bin_size = os.path.getsize(str(out_dir / "code_vectors.bin"))
print()
print("=" * 60)
print(f" model: {MODEL_NAME}")
print(f" tokens: {len(filtered_tokens)}")
print(f" dimensions: {dim}")
print(f" blob size: {bin_size / (1024*1024):.1f} MB")
print(f" sim-attn: {'yes' if not args.skip_attention else 'no'}")
print(f" output: {out_dir}/")
print("=" * 60)
print()
print("next steps:")
print(f" 1. update Makefile.cbm: change UNIXCODER_BLOB_SRC path to vendored/nomic/")
print(f" 2. update #include in semantic.c: \"vendored/nomic/code_vectors.h\"")
print(f" 3. arch -arm64 make -j12 -f Makefile.cbm clean-c && arch -arm64 make -j12 -f Makefile.cbm")
if __name__ == "__main__":
main()