# Trích Xuất SVD Chênh Lệch Trọng Số: Phương Pháp Phổ Quát ## Cách tạo Bộ Điều Hợp LoRA từ Chênh Lệch Trọng Số giữa Hai Mô Hình Kỹ thuật này hoạt động với **bất kỳ kiến trúc LLM nào** có hai bộ điều hợp được huấn luyện từ cùng một mô hình cơ sở. Không cần GPU, không cần dữ liệu huấn luyện, chạy trong 1-3 phút trên CPU. ``` Mô hình A (merged LoRA) Mô hình B (merged LoRA) │ │ └──────────┬─────────────────────┘ │ W_B - W_A = Δ ▼ SVD Cắt Cụt (hạng r) │ ▼ Bộ Điều Hợp LoRA A→B (7 MB) ``` --- ## 1. Điều Kiện ✅ Hoạt động khi: - Cả hai mô hình dùng chung **cùng kiến trúc cơ sở và trọng số cơ sở** (cùng commit hash) - Cả hai mô hình được huấn luyện bằng **LoRA + merge** (không phải full fine-tune) - Tên tensor khớp nhau trên cả hai mô hình - Ít nhất 4 GB RAM để tải 2 tensor cùng lúc ❌ KHÔNG hoạt động khi: - Kiến trúc khác nhau (mô hình cơ sở khác nhau) - Full fine-tune (chênh lệch có thể vượt quá giả định hạng thấp) - config.json / tokenizer bị thay đổi trong quá trình fine-tune - RAM dưới 4 GB --- ## 2. Hướng Dẫn Từng Bước ### Bước 1: Chọn Hai Mô Hình ```python MODEL_A = "lordx64/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled" # Nguồn MODEL_B = "lordx64/Qwen3.6-35B-A3B-Kimi-K2.6-Reasoning-Distilled" # Đích ``` Quy tắc: Cả hai mô hình phải có tên tensor giống hệt và config.json giống hệt. ### Bước 2: Chọn Mô-đun Mục Tiêu Chỉ chọn các lớp tuyến tính bạn muốn trích xuất: ```python TARGET_MODULES = ["q_proj", "k_proj", "v_proj", "o_proj"] # chỉ attention # hoặc TARGET_MODULES = ["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"] # attention + MLP ``` ⚠️ **Quan trọng:** Bỏ qua tensor 3D (ví dụ: lớp chuyên gia MoE `[256, 2048, 512]`) — chúng yêu cầu SVD từng lát phức tạp hơn. ### Bước 3: Chọn Hạng LoRA ```python RANK = 16 # tiêu chuẩn: cân bằng tốt nhất giữa kích thước và chất lượng RANK = 8 # tối thiểu: nhỏ hơn, nhanh hơn, lỗi tái tạo cao hơn RANK = 32 # chất lượng cao: lớn gấp 2, lỗi ít hơn ~4% ``` Mẹo: Chạy phân tích lỗi tái tạo để tìm hạng tối ưu cho trường hợp của bạn. ### Bước 4: Chạy Script Trích Xuất ```bash python3 extract_lora_diff.py \ --model_a lordx64/Qwen3.6-35B-A3B-Claude-4.7-Opus-Reasoning-Distilled \ --model_b lordx64/Qwen3.6-35B-A3B-Kimi-K2.6-Reasoning-Distilled \ --output ./my-lora-adapter \ --rank 16 \ --target_modules q_proj,k_proj,v_proj,o_proj ``` ### Bước 5: Sử Dụng Bộ Điều Hợp **Python (PEFT):** ```python from peft import PeftModel from transformers import AutoModelForCausalLM base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3.6-35B-A3B") model = PeftModel.from_pretrained(base, "./my-lora-adapter") # mô hình bây giờ có phong cách B! ``` **llama.cpp (GGUF):** ```bash # Chuyển đổi sang GGUF trước python3 llama.cpp/convert_lora_to_gguf.py ./my-lora-adapter # Chạy suy luận llama-cli -m base-Q6_K.gguf --lora my-lora-adapter.gguf -p "lời nhắc" ``` --- ## 3. Cơ Sở Toán Học ``` Cho: M_A = W_base + Δ_A (Mô hình A = cơ sở + LoRA A) M_B = W_base + Δ_B (Mô hình B = cơ sở + LoRA B) CL: D = M_B - M_A = Δ_B - Δ_A (cơ sở triệt tiêu, chỉ còn delta) SVD: D ≈ U_r · Σ_r · V_r^T (xấp xỉ hạng r) LoRA: A = √Σ_r · V_r^T (lora_A) B = U_r · √Σ_r (lora_B) Truyền: h = W_0·x + B·A·x (truyền xuôi LoRA chuẩn) ``` **Tại sao nó hoạt động:** - Cả A và B được huấn luyện với LoRA hạng r → chênh lệch của chúng có hạng ≤ 2r - SVD ở hạng r có thể tái tạo chênh lệch gần như hoàn toàn (giữ 91-95% năng lượng) - Không cần huấn luyện — đây là phân rã toán học thuần túy --- ## 4. Ví Dụ Cho Các Mô Hình Khác ### Llama 3.1 8B — Chuyển Đổi Phong Cách ```bash # Hai mô hình fine-tune từ cùng cơ sở Llama-3.1-8B MODEL_A = "user/llama3.1-8b-formal-style" # phong cách trang trọng MODEL_B = "user/llama3.1-8b-casual-style" # phong cách thân mật python3 extract_lora_diff.py \ --model_a user/llama3.1-8b-formal-style \ --model_b user/llama3.1-8b-casual-style \ --output ./llama-formal-to-casual \ --rank 16 \ --target_modules q_proj,k_proj,v_proj,o_proj ``` ### Mistral 7B — Thích Ứng Lĩnh Vực ```bash MODEL_A = "mistralai/Mistral-7B-Instruct-v0.3" # tổng quát MODEL_B = "user/Mistral-7B-medical-finetuned" # lĩnh vực y tế python3 extract_lora_diff.py \ --model_a mistralai/Mistral-7B-Instruct-v0.3 \ --model_b user/Mistral-7B-medical-finetuned \ --output ./mistral-medical-lora \ --rank 16 \ --target_modules q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj ``` ### Qwen2.5 72B — Gỡ Bỏ An Toàn ```bash # Trích xuất delta từ chối giữa phiên bản an toàn và không kiểm duyệt MODEL_A = "Qwen/Qwen2.5-72B-Instruct" # có an toàn MODEL_B = "user/Qwen2.5-72B-uncensored" # không an toàn python3 extract_lora_diff.py \ --model_a Qwen/Qwen2.5-72B-Instruct \ --model_b user/Qwen2.5-72B-uncensored \ --output ./qwen-safety-removal-lora \ --rank 16 ``` --- ## 5. Tham Khảo Tham Số | Tham số | Mặc định | Mô tả | |-----------|---------|-------------| | `--rank` | 16 | Hạng LoRA. Cao hơn = lớn hơn + chất lượng tốt hơn. Thấp hơn = nhỏ hơn + nhanh hơn | | `--target_modules` | q,k,v,o_proj | Mô-đun để trích xuất. Thêm gate/up/down cho MLP | | `--alpha` | 32 | LoRA alpha (hệ số tỉ lệ). Thường gấp 2 lần rank | | `--skip_3d` | True | Tự động bỏ qua tensor 3D (chuyên gia MoE) | | `--output_format` | peft | `peft` hoặc `gguf` hoặc `both` | --- ## 6. Khắc Phục Sự Cố | Vấn đề | Nguyên nhân | Giải pháp | |---------|-------|----------| | `KeyError: tên tensor không khớp` | Mô hình cơ sở khác nhau | Dùng mô hình huấn luyện từ cùng cơ sở | | `CUDA hết bộ nhớ` | Tải toàn bộ mô hình | Dùng chế độ từng-tensor (mặc định) | | `ValueError: tensor không liên tục` | Đầu ra SVD không liên tục | Thêm `.contiguous()` trước khi lưu | | `Chuyển đổi GGUF thất bại` | Tên tensor không khớp | PEFT dùng `.lora_A.default`, GGUF mong `.lora_A.weight` — đổi tên | | `Hạng quá cao cho tensor` | Kích thước tensor < hạng | Giảm hạng hoặc bỏ qua tensor đó | --- ## 7. Hạn Chế 1. **Thiên lệch chỉ-attention**: Chỉ dùng lớp attention có thể bỏ lỡ thay đổi ở lớp FFN/MLP 2. **Giả định hạng thấp**: Tốt nhất với mô hình LoRA-merged; full fine-tune có thể vượt quá hạng 3. **Không đảm bảo chất lượng**: Bộ điều hợp là tái tạo toán học — không bảo đảm khớp chất lượng huấn luyện trực tiếp 4. **Chuyển đổi đơn phong cách**: Chỉ trích xuất sự khác biệt giữa 2 phong cách — cần 3+ phong cách thì tạo nhiều bộ điều hợp --- ## 8. Script Trích Xuất `extract_lora_diff.py` (193 dòng) — script trích xuất sẵn sàng sản xuất có sẵn trong repo này. --- ## 9. Tài Liệu Tham Khảo & Ghi Công - **Kỹ thuật:** UKA (Hermes Agent, Nous Research) & hotdogs - **Bài báo:** [Trích Xuất SVD Chênh Lệch Trọng Số: Tổng Hợp Bộ Điều Hợp LoRA Zero-Shot](https://huggingface.co/hotdogs/qwen3.6-35b-opus-to-kimi-lora/blob/main/paper.pdf) - **Mã + Bộ Điều Hợp:** https://huggingface.co/hotdogs/qwen3.6-35b-opus-to-kimi-lora - **Bài báo LoRA:** Hu et al., 2021 (arXiv:2106.09685) - **Bài báo QLoRA:** Dettmers et al., 2023 (arXiv:2305.14314)