Extract LoRA weights from model difference Args: source_weights: Source model weights target_weights: Target model weights rank: LoRA rank diff_only: If True, save all weights as direct diff without LoRA decomposition Returns: LoRA weights dicti
(source_weights: Dict[str, torch.Tensor], target_weights: Dict[str, torch.Tensor], rank: int = 16, diff_only: bool = False)
| 285 | |
| 286 | |
| 287 | def extract_lora_from_diff(source_weights: Dict[str, torch.Tensor], target_weights: Dict[str, torch.Tensor], rank: int = 16, diff_only: bool = False) -> Dict[str, torch.Tensor]: |
| 288 | """ |
| 289 | Extract LoRA weights from model difference |
| 290 | |
| 291 | Args: |
| 292 | source_weights: Source model weights |
| 293 | target_weights: Target model weights |
| 294 | rank: LoRA rank |
| 295 | diff_only: If True, save all weights as direct diff without LoRA decomposition |
| 296 | |
| 297 | Returns: |
| 298 | LoRA weights dictionary |
| 299 | """ |
| 300 | print("Starting LoRA weight extraction...") |
| 301 | if diff_only: |
| 302 | print("Mode: Direct diff only (no LoRA decomposition)") |
| 303 | else: |
| 304 | print(f"Mode: Smart extraction - rank: {rank}") |
| 305 | print(f"Source model weight count: {len(source_weights)}") |
| 306 | print(f"Target model weight count: {len(target_weights)}") |
| 307 | |
| 308 | lora_weights = {} |
| 309 | processed_count = 0 |
| 310 | diff_count = 0 |
| 311 | lora_count = 0 |
| 312 | similar_count = 0 |
| 313 | skipped_count = 0 |
| 314 | fail_count = 0 |
| 315 | |
| 316 | # Find common keys between two models |
| 317 | common_keys = set(source_weights.keys()) & set(target_weights.keys()) |
| 318 | source_only_keys = set(source_weights.keys()) - set(target_weights.keys()) |
| 319 | target_only_keys = set(target_weights.keys()) - set(source_weights.keys()) |
| 320 | |
| 321 | if source_only_keys: |
| 322 | print(f"Warning: Source model exclusive weight keys ({len(source_only_keys)} keys): {list(source_only_keys)[:5]}...") |
| 323 | if target_only_keys: |
| 324 | print(f"Warning: Target model exclusive weight keys ({len(target_only_keys)} keys): {list(target_only_keys)[:5]}...") |
| 325 | |
| 326 | print(f"Common weight keys count: {len(common_keys)}") |
| 327 | |
| 328 | # Process common keys, extract LoRA weights |
| 329 | common_keys_sorted = sorted(common_keys) |
| 330 | pbar = tqdm(common_keys_sorted, desc="Extracting LoRA weights", unit="layer") |
| 331 | |
| 332 | for key in pbar: |
| 333 | source_tensor = source_weights[key] |
| 334 | target_tensor = target_weights[key] |
| 335 | |
| 336 | # Update progress bar description |
| 337 | short_key = key.split(".")[-2:] if "." in key else [key] |
| 338 | pbar.set_postfix_str(f"Processing: {'.'.join(short_key)}") |
| 339 | |
| 340 | # Compute weight difference |
| 341 | diff = _compute_weight_diff(source_tensor, target_tensor, key) |
| 342 | |
| 343 | if diff is None: |
| 344 | # No change or shape mismatch |
no test coverage detected