| 357 | sys.exit(1) |
| 358 | |
| 359 | class LoraModel(model_class): |
| 360 | model_arch = model_class.model_arch |
| 361 | |
| 362 | lora_alpha: float |
| 363 | |
| 364 | def __init__(self, *args, dir_lora_model: Path, lora_alpha: float, **kwargs): |
| 365 | |
| 366 | super().__init__(*args, **kwargs) |
| 367 | |
| 368 | self.dir_model_card = dir_lora_model |
| 369 | self.lora_alpha = float(lora_alpha) |
| 370 | |
| 371 | def set_vocab(self): |
| 372 | pass |
| 373 | |
| 374 | def set_type(self): |
| 375 | self.gguf_writer.add_type(gguf.GGUFType.ADAPTER) |
| 376 | self.gguf_writer.add_string(gguf.Keys.Adapter.TYPE, "lora") |
| 377 | |
| 378 | def set_gguf_parameters(self): |
| 379 | logger.debug("GGUF KV: %s = %d", gguf.Keys.Adapter.LORA_ALPHA, self.lora_alpha) |
| 380 | self.gguf_writer.add_float32(gguf.Keys.Adapter.LORA_ALPHA, self.lora_alpha) |
| 381 | alora_invocation_tokens = lparams.get("alora_invocation_tokens") |
| 382 | invocation_string = lparams.get("invocation_string") |
| 383 | if invocation_string and not alora_invocation_tokens: |
| 384 | logger.debug("Tokenizing invocation_string -> alora_invocation_tokens") |
| 385 | base_model_path_or_id = hparams.get("_name_or_path") |
| 386 | try: |
| 387 | tokenizer = AutoTokenizer.from_pretrained(base_model_path_or_id) |
| 388 | except ValueError: |
| 389 | logger.error("Unable to load tokenizer from %s", base_model_path_or_id) |
| 390 | raise |
| 391 | # NOTE: There's an off-by-one with the older aLoRAs where |
| 392 | # the invocation string includes the "<|start_of_turn|>" |
| 393 | # token, but the adapters themselves were trained to |
| 394 | # activate _after_ that first token, so we drop it here. |
| 395 | alora_invocation_tokens = tokenizer(invocation_string)["input_ids"][1:] |
| 396 | if alora_invocation_tokens: |
| 397 | logger.debug("GGUF KV: %s = %s", gguf.Keys.Adapter.ALORA_INVOCATION_TOKENS, alora_invocation_tokens) |
| 398 | self.gguf_writer.add_key_value( |
| 399 | gguf.Keys.Adapter.ALORA_INVOCATION_TOKENS, |
| 400 | alora_invocation_tokens, |
| 401 | GGUFValueType.ARRAY, |
| 402 | GGUFValueType.UINT32, |
| 403 | ) |
| 404 | |
| 405 | def generate_extra_tensors(self) -> Iterable[tuple[str, Tensor]]: |
| 406 | # Never add extra tensors (e.g. rope_freqs) for LoRA adapters |
| 407 | return () |
| 408 | |
| 409 | def get_tensors(self) -> Iterator[tuple[str, Tensor]]: |
| 410 | tensor_map: dict[str, PartialLoraTensor] = {} |
| 411 | |
| 412 | for name, tensor in lora_model.items(): |
| 413 | if self.lazy: |
| 414 | tensor = LazyTorchTensor.from_eager(tensor) |
| 415 | base_name = get_base_tensor_name(name) |
| 416 | # note: mergekit-extract-lora also adds token embeddings to the adapter |
no outgoing calls
no test coverage detected