(self, request, context)
| 144 | |
| 145 | |
| 146 | def LoadModel(self, request, context): |
| 147 | try: |
| 148 | import torch |
| 149 | |
| 150 | self.options = parse_options(request.Options) |
| 151 | if self.options.get("voice") and self.options["voice"] not in VOICE_PROMPTS: |
| 152 | print(f"Warning: unknown voice '{self.options['voice']}'; defaulting to '{DEFAULT_VOICE}'", |
| 153 | file=sys.stderr) |
| 154 | |
| 155 | requested_device = self.options.get("device") |
| 156 | self.device = requested_device or _select_device() |
| 157 | if self.device == "cuda" and not torch.cuda.is_available(): |
| 158 | return backend_pb2.Result(success=False, message="CUDA requested but not available") |
| 159 | if self.device == "mps" and not (hasattr(torch.backends, "mps") and |
| 160 | torch.backends.mps.is_available()): |
| 161 | print("MPS not available; falling back to CPU", file=sys.stderr) |
| 162 | self.device = "cpu" |
| 163 | |
| 164 | dtype_name = str(self.options.get("dtype", "bfloat16")).lower() |
| 165 | self.dtype = { |
| 166 | "bfloat16": torch.bfloat16, |
| 167 | "bf16": torch.bfloat16, |
| 168 | "float16": torch.float16, |
| 169 | "fp16": torch.float16, |
| 170 | "half": torch.float16, |
| 171 | "float32": torch.float32, |
| 172 | "fp32": torch.float32, |
| 173 | }.get(dtype_name, torch.bfloat16) |
| 174 | |
| 175 | # request.Model holds the raw `parameters.model` value (an HF |
| 176 | # repo id like "LiquidAI/LFM2.5-Audio-1.5B"); request.ModelFile |
| 177 | # is LocalAI's ModelPath-prefixed local copy that exists only |
| 178 | # when the gallery supplied a `files:` list. Mirror the |
| 179 | # transformers/vibevoice convention: prefer the repo id and |
| 180 | # only switch to the local path if it's been staged on disk. |
| 181 | model_id = request.Model |
| 182 | if not model_id: |
| 183 | model_id = request.ModelFile |
| 184 | if not model_id: |
| 185 | return backend_pb2.Result(success=False, message="No model identifier provided") |
| 186 | if request.ModelFile and os.path.isdir(request.ModelFile): |
| 187 | model_id = request.ModelFile |
| 188 | self.model_id = model_id |
| 189 | |
| 190 | # Pure fine-tune jobs don't need an in-memory inference model — the |
| 191 | # Trainer instantiates its own copy at StartFineTune time. |
| 192 | if self.mode == "finetune": |
| 193 | print(f"Loaded liquid-audio backend in fine-tune mode (model id: {model_id})", |
| 194 | file=sys.stderr) |
| 195 | return backend_pb2.Result(success=True, message="OK") |
| 196 | |
| 197 | from liquid_audio import LFM2AudioModel, LFM2AudioProcessor |
| 198 | |
| 199 | # liquid_audio's from_pretrained unconditionally routes through |
| 200 | # huggingface_hub.snapshot_download, which rejects local paths |
| 201 | # (HFValidationError on `/models/LiquidAI/LFM2.5-Audio-1.5B`). |
| 202 | # When LocalAI's gallery has already staged the weights on disk, |
| 203 | # short-circuit the download to return the local directory. |
nothing calls this directly
no test coverage detected