import os import torch MPS_FALLBACK_ENV = "PYTORCH_ENABLE_MPS_FALLBACK" FAST_MAX_NEW_TOKENS = 96 FAST_TEMPERATURE = 0.0 FAST_TOP_P = 1.0 def enable_mps_fallback(): os.environ.setdefault(MPS_FALLBACK_ENV, "1") def choose_device(allow_cpu=False, requested_device="auto"): if requested_device not in {"auto", "cuda", "mps", "cpu"}: raise ValueError( "requested_device must be one of: auto, cuda, mps, cpu" ) if requested_device in {"auto", "cuda"} and torch.cuda.is_available(): return { "name": "cuda", "device": torch.device("cuda"), "device_map": "auto", "torch_dtype": torch.bfloat16, "move_after_load": False, } mps_available = ( getattr(torch.backends, "mps", None) and torch.backends.mps.is_available() and torch.backends.mps.is_built() ) if requested_device in {"auto", "mps"} and mps_available: enable_mps_fallback() return { "name": "mps", "device": torch.device("mps"), "device_map": None, "torch_dtype": torch.float16, "move_after_load": True, } if requested_device == "cpu" or allow_cpu: return { "name": "cpu", "device": torch.device("cpu"), "device_map": None, "torch_dtype": torch.float32, "move_after_load": False, } if requested_device == "cuda": raise RuntimeError("CUDA was requested, but no CUDA GPU was detected.") if requested_device == "mps": raise RuntimeError( "Apple MPS was requested, but this Python environment cannot use it. " "Use an Apple Silicon Mac and a PyTorch build with MPS support." ) raise RuntimeError( "No CUDA or Apple MPS GPU detected. Re-run with CPU fallback enabled for " "slow CPU mode." ) def model_load_kwargs(runtime): kwargs = { "dtype": runtime["torch_dtype"], "low_cpu_mem_usage": True, "trust_remote_code": True, "attn_implementation": "sdpa", } if runtime["device_map"] is not None: kwargs["device_map"] = runtime["device_map"] return kwargs def adapter_load_kwargs(runtime): if runtime["name"] == "mps": return { "torch_device": "cpu", "autocast_adapter_dtype": True, } return {} def place_model(model, runtime): if runtime["move_after_load"]: model = model.to(runtime["device"]) if hasattr(model, "generation_config"): model.generation_config.use_cache = True return model def resolve_generation_settings(max_new_tokens, temperature, top_p, fast=False): if fast: return { "max_new_tokens": ( FAST_MAX_NEW_TOKENS if max_new_tokens is None else max_new_tokens ), "temperature": FAST_TEMPERATURE if temperature is None else temperature, "top_p": FAST_TOP_P if top_p is None else top_p, } return { "max_new_tokens": 300 if max_new_tokens is None else max_new_tokens, "temperature": 0.2 if temperature is None else temperature, "top_p": 0.9 if top_p is None else top_p, }