Files
nvlabs--longlive/fouroversix/scripts/ptq/evaluators/utils.py
T
2026-07-13 12:31:40 +08:00

101 lines
3.3 KiB
Python

from typing import Any
import torch
from inspect_ai.model import modelapi
from inspect_ai.model._generate_config import GenerateConfig
from inspect_ai.model._providers.hf import HuggingFaceAPI
from transformers import AutoModelForCausalLM, AutoTokenizer
def set_random_seeds(seed: int | None = None) -> None:
import os
import numpy as np
from transformers import set_seed
if seed is None:
seed = np.random.default_rng().integers(2**32 - 1)
# python hash seed
os.environ["PYTHONHASHSEED"] = str(seed)
# transformers seed
set_seed(seed)
class LocalHuggingFaceAPI(HuggingFaceAPI):
"""
Wrapper around HuggingFaceAPI that allows for quantized models to be used during
evaluation.
"""
def __init__( # noqa: C901
self,
model_name: str,
model: AutoModelForCausalLM,
config: GenerateConfig | None = None,
**model_args: dict[str, Any],
) -> None:
self.model_name = model_name
self.base_url = None
self.api_key = None
self.api_key_vars = ["HF_TOKEN"]
self._apply_api_key_overrides()
if config is None:
config = GenerateConfig()
# set random seeds
if config.seed is not None:
set_random_seeds(config.seed)
# collect known model_args (then delete them so we can pass the rest on)
def collect_model_arg(name: str) -> Any | None: # noqa: ANN401
nonlocal model_args
value = model_args.get(name)
if value is not None:
model_args.pop(name)
return value
device = collect_model_arg("device")
tokenizer = collect_model_arg("tokenizer")
model_path = collect_model_arg("model_path")
tokenizer_path = collect_model_arg("tokenizer_path")
self.batch_size = collect_model_arg("batch_size")
self.chat_template = collect_model_arg("chat_template")
self.tokenizer_call_args = collect_model_arg("tokenizer_call_args")
self.enable_thinking = collect_model_arg("enable_thinking")
if self.tokenizer_call_args is None:
self.tokenizer_call_args = {}
self.hidden_states = collect_model_arg("hidden_states")
# device
if device:
self.device = device
elif torch.backends.mps.is_available():
self.device = "mps"
elif torch.cuda.is_available():
self.device = "cuda:0"
else:
self.device = "cpu"
# model
self.model = model
# tokenizer
if tokenizer:
self.tokenizer = AutoTokenizer.from_pretrained(tokenizer) # type: ignore[no-untyped-call]
elif model_path:
if tokenizer_path:
self.tokenizer = AutoTokenizer.from_pretrained(tokenizer_path) # type: ignore[no-untyped-call]
else:
self.tokenizer = AutoTokenizer.from_pretrained(model_path) # type: ignore[no-untyped-call]
else:
self.tokenizer = AutoTokenizer.from_pretrained(model_name) # type: ignore[no-untyped-call]
# LLMs generally don't have a pad token and we need one for batching
self.tokenizer.pad_token = self.tokenizer.eos_token
self.tokenizer.padding_side = "left"
@modelapi(name="local_hf")
def local_hf() -> type[LocalHuggingFaceAPI]:
return LocalHuggingFaceAPI