Sor0ush's picture
|
download
raw
12.8 kB

SVC: Singular Value Calibration for Model Merging

Python PyTorch Paper License: MIT

English | ไธญๆ–‡

Training-free and data-free singular value calibration for robust model merging across shared subspaces.

๐Ÿ“ฐ News

  • ๐Ÿ’ฅ2026-05-01: Our paper is accepted by ICML'26. See you all in Seoul, Korea!
  • ๐Ÿ’ฅ2026-03-20: We appreciate Anke Tang for including our work in fusion_bench!
  • ๐Ÿ’ฅ2026-02-05: We have submitted our paper to arXiv.

๐Ÿ”— Quick Links

๐Ÿงญ Contents

๐Ÿ“‹ Project Overview

Model merging combines multiple fine-tuned models into a single model by adding their weight updates, providing a lightweight alternative to retraining. Existing methods primarily target resolving conflicts between task updates, leaving the failure mode of over-counting shared knowledge unaddressed. We show that when tasks share aligned spectral directions (i.e., overlapping singular vectors), a simple linear combination repeatedly accumulates these directions, inflating the singular values and biasing the merged model toward shared subspaces. To mitigate this issue, we propose Singular Value Calibration (SVC), a training-free and data-free post-processing method that quantifies subspace overlap and rescales inflated singular values to restore a balanced spectrum. Across vision and language benchmarks, SVC consistently improves strong merging baselines and achieves state-of-the-art performance. Furthermore, by modifying only the singular values, SVC improves the performance of Task Arithmetic by 13.0%.

Highlights

  • Training-free and data-free post-processing for model merging.
  • Targets spectral over-counting in shared singular directions.
  • Plug-and-play with common merging baselines (TA, TIES, STAR, TSV-M, Iso-*).
  • Strong empirical gains across vision and language benchmarks.

overview

๐Ÿš€ Quick Start (5 Minutes)

1๏ธโƒฃ Environment Setup

# Create environment from environment.yml
conda env create -f environment.yml -n SVC
conda activate SVC

2๏ธโƒฃ Prepare Checkpoints

Download from Google Drive and organize:

checkpoints/
โ””โ”€โ”€ ViT-B-32/
    โ”œโ”€โ”€ zeroshot.pt                    # Pre-trained CLIP
    โ”œโ”€โ”€ Cars/finetuned.pt
    โ”œโ”€โ”€ DTD/finetuned.pt
    โ””โ”€โ”€ ... (other tasks)

3๏ธโƒฃ Run Your First Experiment

# Task Arithmetic (baseline)
python main.py --model ViT-B-32 --merge TA

# Task Arithmetic + SVC (calibrated)
python main.py --model ViT-B-32 --merge TA --c

# Try all methods
bash run.sh

โœ… Results will appear in logs/ViT-B-32/log_*.txt


๐Ÿ“– Detailed Usage Guide

Command Line Reference

python main.py [OPTIONS]
Option Default Description
--model ViT-B-32 Model architecture (ViT-B-32, ViT-L-14, etc.)
--merge TA Merging method (TA, TSV-M, etc.)
--c False Enable Support Vector Calibration
--alpha 0.1 Calibration weight parameter
--scaling_coef 1.0 Task vector scaling factor
--base_dir . Base directory for checkpoints

Available Merging Methods

Method Description Best For Link
TA Task Arithmetic (simple average) Baseline, fast link
TIES Sign-alignment sparse merging Conflict reduction link
DARE Randomized task vector selection Regularization link
TSV-M Task singular vectors merging Spectral alignment link
Iso-C Isolated common subspace Common-space control link
Iso-CTS Common + task-specific subspaces Fine-grained decomposition link
STAR Spectral task arithmetic Non-uniform spectrum link

Usage Examples

Example 1: Reproduce Baseline Results

python main.py --model ViT-B-32 --merge TA --scaling_coef 0.3

Example 2: Use SVC for Better Performance

python main.py --model ViT-B-32 --merge TA --c --alpha 0.5

Example 3: Compare Multiple Methods

for method in TA WA TIES STAR; do
  python main.py --model ViT-B-32 --merge $method --c
done

Example 4: Batch Processing (All Methods)

bash run.sh

๐Ÿ“ Project Structure

SVC/
โ”œโ”€โ”€ main.py                    # Main entry point
โ”œโ”€โ”€ merge_func.py              # All merging algorithm implementations
โ”œโ”€โ”€ run.sh                     # Batch script to run all experiments
โ”œโ”€โ”€ utils.py                   # Common utilities
โ”‚
โ”œโ”€โ”€ clip/                      # CLIP model implementation
โ”‚   โ”œโ”€โ”€ clip.py
โ”‚   โ”œโ”€โ”€ model.py               # ViT architecture
โ”‚   โ””โ”€โ”€ simple_tokenizer.py    # Tokenization
โ”‚
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ args.py                # Argument parsing
โ”‚   โ”œโ”€โ”€ eval.py                # Evaluation on multiple datasets
โ”‚   โ”œโ”€โ”€ modeling.py            # Model instantiation
โ”‚   โ”œโ”€โ”€ task_vectors.py        # TaskVector class - core data structure
โ”‚   โ”œโ”€โ”€ ties_merging_utils.py  # TIES algorithm utilities
โ”‚   โ”‚
โ”‚   โ””โ”€โ”€ datasets/              # Dataset implementations
โ”‚       โ”œโ”€โ”€ registry.py        # Dataset registry & factory
โ”‚       โ”œโ”€โ”€ common.py          # Base dataset class
โ”‚       โ”œโ”€โ”€ cifar10.py
โ”‚       โ”œโ”€โ”€ cifar100.py
โ”‚       โ”œโ”€โ”€ imagenet.py
โ”‚       โ””โ”€โ”€ ... (20+ datasets)
โ”‚
โ”œโ”€โ”€ logs/                      # Output logs (auto-created)
โ”‚   โ””โ”€โ”€ ViT-B-32/
โ”‚       โ””โ”€โ”€ log_*.txt
โ”‚
โ””โ”€โ”€ checkpoints/               # Model checkpoints (external)
    โ””โ”€โ”€ ViT-B-32/
        โ”œโ”€โ”€ zeroshot.pt
        โ””โ”€โ”€ */finetuned.pt

๐ŸŽ“ Technical Background

Core Concepts

Task Vector: The difference between fine-tuned and pre-trained weights: ฯ„i=ฮธft,iโˆ’ฮธpt\tau_i = \theta_{ft,i} - \theta_{pt}

Merging Task: Combine n task vectors into a single merged model while preserving knowledge: ฮธmerged=ฮธpt+Merge(ฯ„1,ฯ„2,...,ฯ„n)\theta_{merged} = \theta_{pt} + \text{Merge}(\tau_1, \tau_2, ..., \tau_n)

Support Vector Calibration: Our proposed method identifies and weights critical parameters for better merging.

Why Task Vector Merging?

  1. โœ… No Task ID Needed: Merged model works on all tasks without task-specific routing
  2. โœ… Parameter Efficient: Single model replaces N fine-tuned models
  3. โœ… Knowledge Preservation: Combines learned knowledge across tasks
  4. โš ๏ธ Challenge: Preventing negative transfer between tasks

๐Ÿ”ง Advanced Usage

Custom Merging Method

Add new method to merge_func.py:

@torch.no_grad()
def MyMethod(task_vector_avg, task_vectors, config):
    """
    Args:
        task_vector_avg: Initial averaged task vector
        task_vectors: List[TaskVector] of all tasks  
        config: Configuration object with hyperparameters
    
    Returns:
        TaskVector: Merged task vector
    """
    # Your implementation
    print(f"Processing {len(task_vectors)} task vectors...")
    for key in task_vector_avg.vector:
        # Modify task_vector_avg.vector[key]
        pass
    return task_vector_avg

Then register in main.py:

merge_methods = {
    'TA': TA,
    'MyMethod': MyMethod,
}

Dataset Extension

  1. Create new dataset class in src/datasets/:
from src.datasets.common import AbstractDataset

class MyDataset(AbstractDataset):
    def __init__(self, root, split='train'):
        # Load your dataset
        pass
  1. Register in src/datasets/registry.py

๐Ÿ“Š Experimental Results

Typical evaluation metrics:

  • Accuracy per dataset
  • Average accuracy across all tasks
  • Runtime and memory consumption

Results logged in: logs/ViT-B-32/log_YYYYMMDD_HHMMSS_mainV2.txt


โš ๏ธ Troubleshooting

Problem: Checkpoint Loading Fails

RuntimeError: Unable to load checkpoint

Solution: Use pickle instead of torch.load

import pickle
ckpt = pickle.load(open('checkpoint.pt', 'rb'))
state = ckpt.state_dict() if hasattr(ckpt, 'state_dict') else ckpt

Problem: Slow Evaluation

Solutions:

  • Use GPU: ensure CUDA is available
  • Reduce number of evaluation samples
  • Use multiprocessing in eval.py

๐Ÿ“š Related Work & References


๐Ÿ“ Citation

If this work helps your research, please cite:

@article{SVC2026,
  title={When Shared Knowledge Hurts: Spectral Over-Accumulation in Model Merging},
  author={Li, Yayuan and Peng, Ze and Zhang, Jian and Guo, Jintao and Duan, Yue and Shi, Yinghuan},
  journal={arXiv preprint arXiv:2602.05536},
  year={2026}
}

๐Ÿ“„ License

MIT License - See LICENSE file for details

๐Ÿค Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request

ไธญๆ–‡็‰ˆๆœฌ

ไธ€ๅฅ่ฏ็ฎ€ไป‹๏ผšSVC ๆ˜ฏไธ€็งๆ— ้œ€่ฎญ็ปƒใ€ๆ— ้œ€ๆ•ฐๆฎ็š„ๅฅ‡ๅผ‚ๅ€ผๆ กๅ‡†ๆ–นๆณ•๏ผŒ็”จไบŽๆๅ‡ๅคšไปปๅŠกๆจกๅž‹่žๅˆ็š„็จณๅฎšๆ€งไธŽๆณ›ๅŒ–ๆ€ง่ƒฝใ€‚

๐Ÿ”— ๅฟซ้€Ÿๅฏผ่ˆช

้กน็›ฎๆฆ‚่ฟฐ

SVC ๆ˜ฏไธ€ไธชๅ…ˆ่ฟ›็š„ๆจกๅž‹่žๅˆๆก†ๆžถ๏ผŒ่ฏฅ้กน็›ฎๅŸบไบŽ Task Vectors ็š„็ ”็ฉถ๏ผŒๆๅ‡บไบ† ๅฅ‡ๅผ‚ๅ€ผๆ กๅ‡†๏ผˆSVC๏ผ‰ ๆ–นๆณ•ๆฅๅฎž็Žฐๅคšไธชๅพฎ่ฐƒๆจกๅž‹็š„็จณๅฎš้ซ˜ๆ•ˆ่žๅˆใ€‚

๐Ÿš€ 5 ๅˆ†้’Ÿๅฟซ้€Ÿๅผ€ๅง‹

# 1. ็Žฏๅขƒ้…็ฝฎ
conda create -n svc python=3.10 -y
conda activate svc
pip install torch torchvision transformers scipy tqdm Pillow

# 2. ไธ‹่ฝฝๆจกๅž‹ๆฃ€ๆŸฅ็‚นๅˆฐ checkpoints/ViT-B-32/

# 3. ่ฟ่กŒ็ฌฌไธ€ไธชๅฎž้ชŒ
python main.py --model ViT-B-32 --merge TA
python main.py --model ViT-B-32 --merge TA --c  # ไฝฟ็”จ SVC
bash run.sh  # ่ฟ่กŒๆ‰€ๆœ‰ๆ–นๆณ•

๐Ÿ“– ไฝฟ็”จๆŒ‡ๅ—

python main.py [OPTIONS]

ไธป่ฆๅ‚ๆ•ฐ๏ผš

  • --model: ๆจกๅž‹ๆžถๆž„ (ViT-B-32, ViT-L-14 ็ญ‰)
  • --merge: ๅˆๅนถๆ–นๆณ• (TA, WA, SA, TIES, DARE, STAR, iso_c, iso_cts ็ญ‰)
  • --c: ๅฏ็”จๆ”ฏๆŒๅ‘้‡ๆ กๅ‡†
  • --alpha: ๆ กๅ‡†ๆƒ้‡ๅ‚ๆ•ฐ
  • --scaling_coef: ไปปๅŠกๅ‘้‡็ผฉๆ”พ็ณปๆ•ฐ

๐ŸŽ“ ๆ ธๅฟƒๆฆ‚ๅฟต

ไปปๅŠกๅ‘้‡๏ผšๅพฎ่ฐƒๆƒ้‡ไธŽ้ข„่ฎญ็ปƒๆƒ้‡็š„ๅทฎ๏ผš ฯ„i=ฮธft,iโˆ’ฮธpt\tau_i = \theta_{ft,i} - \theta_{pt}

ๅˆๅนถ็›ฎๆ ‡๏ผšๅฐ† n ไธชไปปๅŠกๅ‘้‡ๅˆๅนถๆˆๅ•ไธชๆจกๅž‹๏ผŒๅŒๆ—ถไฟ็•™ๆ‰€ๆœ‰ไปปๅŠก็š„็Ÿฅ่ฏ†๏ผš ฮธmerged=ฮธpt+Merge(ฯ„1,ฯ„2,...,ฯ„n)\theta_{merged} = \theta_{pt} + \text{Merge}(\tau_1, \tau_2, ..., \tau_n)

๐Ÿ”ง ๆ‰ฉๅฑ•ไธŽๅฎšๅˆถ

ๅฏไปฅ่ฝปๆพๆทปๅŠ ๆ–ฐ็š„ๅˆๅนถๆ–นๆณ•ใ€ๆ•ฐๆฎ้›†ๅ’Œๆจกๅž‹ใ€‚่ฏฆ่งๆบ็ ๆณจ้‡Šใ€‚


Xet Storage Details

Size:
12.8 kB
ยท
Xet hash:
76a6d862e51b423f574255537c8ad70faf1f41386121d76bee7fe81abaca75a2

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.