geocine's picture
Revert to 350M CPU Space; add notice linking to 2.6B creative Space
3a01f1b verified
Raw
History Blame Contribute Delete
2.45 kB
"""Model/tokenizer loading and stop-token resolution."""
from __future__ import annotations
from pathlib import Path
from ..paths import BASE_MODEL
def resolve_model_dir(model: str | Path) -> tuple[str, str | None]:
"""Return (model_path, adapter_path). Prefers merged weights when present."""
p = Path(model)
if p.is_dir():
if (p / "merged").is_dir() and (p / "merged" / "config.json").is_file():
return str(p / "merged"), None
if (p / "config.json").is_file():
return str(p), None
if (p / "adapter_config.json").is_file():
return BASE_MODEL, str(p)
return str(model), None
def load_model_and_tokenizer(model: str | Path, *, prefer_cpu: bool = False):
"""Load HF causal LM. Set prefer_cpu=True to force CPU float32 (no CUDA map)."""
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_path, adapter_path = resolve_model_dir(model)
tokenizer = AutoTokenizer.from_pretrained(adapter_path or model_path, trust_remote_code=True)
use_cuda = torch.cuda.is_available() and not prefer_cpu
dtype = torch.bfloat16 if use_cuda else torch.float32
device_map = "auto" if use_cuda else "cpu"
lm = AutoModelForCausalLM.from_pretrained(
model_path, trust_remote_code=True, device_map=device_map, torch_dtype=dtype
)
if adapter_path:
from peft import PeftModel
lm = PeftModel.from_pretrained(lm, adapter_path).merge_and_unload()
lm.eval()
return lm, tokenizer
def build_stop_ids(tokenizer) -> list[int]:
"""ChatML / LFM end tokens for clean stopping."""
candidates = ["<|im_end|>", "<|endoftext|>", tokenizer.eos_token]
ids: list[int] = []
for s in candidates:
if not s:
continue
try:
tid = tokenizer.convert_tokens_to_ids(s)
if tid is not None and tid != tokenizer.unk_token_id and int(tid) >= 0:
ids.append(int(tid))
except Exception:
pass
try:
enc = tokenizer.encode(s, add_special_tokens=False)
if len(enc) == 1:
ids.append(int(enc[0]))
except Exception:
pass
out: list[int] = []
for i in ids:
if i not in out:
out.append(i)
if tokenizer.eos_token_id is not None and tokenizer.eos_token_id not in out:
out.append(int(tokenizer.eos_token_id))
return out