Commit ·
c4cbe0b
1
Parent(s): e7fb333
NoGPU 0.2
Browse files- .gitignore +0 -6
- core/compressor.py +11 -4
- core/scorer.py +10 -1
- models/model_loader.py +3 -3
.gitignore
CHANGED
|
@@ -5,12 +5,6 @@ my-notes
|
|
| 5 |
.env
|
| 6 |
.venv
|
| 7 |
|
| 8 |
-
# I did use vibe code 😉
|
| 9 |
-
.claude
|
| 10 |
-
CLAUDE.md
|
| 11 |
-
AGENTS.md
|
| 12 |
-
claude*
|
| 13 |
-
|
| 14 |
# Caches
|
| 15 |
__pycache__
|
| 16 |
*.db
|
|
|
|
| 5 |
.env
|
| 6 |
.venv
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
# Caches
|
| 9 |
__pycache__
|
| 10 |
*.db
|
core/compressor.py
CHANGED
|
@@ -1,9 +1,14 @@
|
|
| 1 |
import torch
|
| 2 |
-
import spaces
|
| 3 |
import config
|
| 4 |
from core.tokenizer_utils import count_tokens
|
| 5 |
from models.model_loader import get_llm
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
|
| 8 |
_PROMPT_TEMPLATE = """You are a lossless compression assistant. Compress the following text to at most {target} tokens.
|
| 9 |
Preserve all key facts, decisions, and intent. Do not add commentary. Output only the compressed text.
|
|
@@ -13,10 +18,13 @@ TEXT:
|
|
| 13 |
|
| 14 |
COMPRESSED:"""
|
| 15 |
|
| 16 |
-
|
|
|
|
| 17 |
def _generate(prompt: str) -> str:
|
| 18 |
model, tokenizer = get_llm()
|
| 19 |
-
|
|
|
|
|
|
|
| 20 |
with torch.no_grad():
|
| 21 |
output_ids = model.generate(
|
| 22 |
**inputs,
|
|
@@ -32,7 +40,6 @@ def compress(text: str, target_tokens: int) -> tuple[str, int, int]:
|
|
| 32 |
"""Returns (compressed_text, input_token_count, output_token_count)."""
|
| 33 |
input_tokens = count_tokens(text)
|
| 34 |
|
| 35 |
-
# If already within budget, return as-is
|
| 36 |
if input_tokens <= target_tokens:
|
| 37 |
return text, input_tokens, input_tokens
|
| 38 |
|
|
|
|
| 1 |
import torch
|
|
|
|
| 2 |
import config
|
| 3 |
from core.tokenizer_utils import count_tokens
|
| 4 |
from models.model_loader import get_llm
|
| 5 |
|
| 6 |
+
try:
|
| 7 |
+
import spaces
|
| 8 |
+
_gpu = spaces.GPU
|
| 9 |
+
except ImportError:
|
| 10 |
+
_gpu = lambda fn: fn # no-op when running locally without the spaces package
|
| 11 |
+
|
| 12 |
|
| 13 |
_PROMPT_TEMPLATE = """You are a lossless compression assistant. Compress the following text to at most {target} tokens.
|
| 14 |
Preserve all key facts, decisions, and intent. Do not add commentary. Output only the compressed text.
|
|
|
|
| 18 |
|
| 19 |
COMPRESSED:"""
|
| 20 |
|
| 21 |
+
|
| 22 |
+
@_gpu
|
| 23 |
def _generate(prompt: str) -> str:
|
| 24 |
model, tokenizer = get_llm()
|
| 25 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 26 |
+
model.to(device)
|
| 27 |
+
inputs = tokenizer(prompt, return_tensors="pt").to(device)
|
| 28 |
with torch.no_grad():
|
| 29 |
output_ids = model.generate(
|
| 30 |
**inputs,
|
|
|
|
| 40 |
"""Returns (compressed_text, input_token_count, output_token_count)."""
|
| 41 |
input_tokens = count_tokens(text)
|
| 42 |
|
|
|
|
| 43 |
if input_tokens <= target_tokens:
|
| 44 |
return text, input_tokens, input_tokens
|
| 45 |
|
core/scorer.py
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
from models.model_loader import get_embedder
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
|
|
|
|
|
|
| 5 |
def semantic_score(original: str, compressed: str) -> float:
|
| 6 |
embedder = get_embedder()
|
| 7 |
-
|
|
|
|
| 8 |
cos = float(
|
| 9 |
np.dot(vecs[0], vecs[1]) / (np.linalg.norm(vecs[0]) * np.linalg.norm(vecs[1]))
|
| 10 |
)
|
|
|
|
| 1 |
+
import torch
|
| 2 |
import numpy as np
|
| 3 |
from models.model_loader import get_embedder
|
| 4 |
|
| 5 |
+
try:
|
| 6 |
+
import spaces
|
| 7 |
+
_gpu = spaces.GPU
|
| 8 |
+
except ImportError:
|
| 9 |
+
_gpu = lambda fn: fn # no-op when running locally without the spaces package
|
| 10 |
|
| 11 |
+
|
| 12 |
+
@_gpu
|
| 13 |
def semantic_score(original: str, compressed: str) -> float:
|
| 14 |
embedder = get_embedder()
|
| 15 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 16 |
+
vecs = embedder.encode([original, compressed], device=device, convert_to_numpy=True)
|
| 17 |
cos = float(
|
| 18 |
np.dot(vecs[0], vecs[1]) / (np.linalg.norm(vecs[0]) * np.linalg.norm(vecs[1]))
|
| 19 |
)
|
models/model_loader.py
CHANGED
|
@@ -43,11 +43,11 @@ def switch_llm(model_id: str) -> str:
|
|
| 43 |
def _load_llm(model_id: str):
|
| 44 |
"""Load model + its paired tokenizer. Both come from the same model_id."""
|
| 45 |
global _llm, _tokenizer, _current_model_id
|
| 46 |
-
_tokenizer = AutoTokenizer.from_pretrained(model_id)
|
| 47 |
_llm = AutoModelForCausalLM.from_pretrained(
|
| 48 |
model_id,
|
| 49 |
-
torch_dtype=
|
| 50 |
-
device_map=
|
| 51 |
)
|
| 52 |
_llm.eval()
|
| 53 |
_current_model_id = model_id
|
|
|
|
| 43 |
def _load_llm(model_id: str):
|
| 44 |
"""Load model + its paired tokenizer. Both come from the same model_id."""
|
| 45 |
global _llm, _tokenizer, _current_model_id
|
| 46 |
+
_tokenizer = AutoTokenizer.from_pretrained(model_id)
|
| 47 |
_llm = AutoModelForCausalLM.from_pretrained(
|
| 48 |
model_id,
|
| 49 |
+
torch_dtype="auto", # uses model's native dtype (bfloat16 for Qwen2.5)
|
| 50 |
+
device_map=None, # load to CPU; @spaces.GPU functions move it on demand
|
| 51 |
)
|
| 52 |
_llm.eval()
|
| 53 |
_current_model_id = model_id
|