MergeKit Tutorial: Merging LLM Models to Create Custom AI Models

# Tutorial MergeKit: Menggabungkan Model LLM untuk Membuat Model AI Kustom Model bahasa besar (LLM) open-source terus berkembang pesat. Dengan banyaknya model fine-tuned yang tersedia di Hugging Face...

By Ruby Abdullah · · tutorial
MergeKitLLMModel MergingHugging FacePython

MergeKit Tutorial: Merging LLM Models to Create Custom AI Models

Open-source large language models (LLMs) continue to evolve rapidly. With numerous fine-tuned models available on Hugging Face, an interesting technique has emerged that allows us to combine multiple models into a single new model without any retraining. This technique is called model merging, and MergeKit is the most popular toolkit for doing it.

MergeKit, developed by Arcee AI, enables us to merge two or more transformer models using various methods such as SLERP, TIES, DARE, and linear merge. The result is a new model that combines capabilities from the source models without requiring GPU resources for training.

In this tutorial, we will learn how to use MergeKit from installation to creating a merged model ready for deployment.

Why Model Merging?

Before diving into the techniques, it is important to understand why model merging has become popular:

  • No Training Required: Model merging does not require GPUs or training datasets. The process is purely weight tensor manipulation.
  • Capability Combination: A model fine-tuned for coding can be merged with one excelling at reasoning, producing a model capable of both.
  • Efficient: The merge process can run on CPU with sufficient RAM, without expensive GPU clusters.
  • Fast Experimentation: You can try various model combinations and merge methods in minutes.
  • Active Community: Many top models on the Open LLM Leaderboard are merge results.
  • Installing MergeKit

    Prerequisites

    • Python 3.10 or newer
    • Minimum 16 GB RAM (depends on model size)
    • Sufficient disk space to store models (each 7B model requires approximately 14 GB in fp16)

    Install from PyPI

    pip install mergekit
    

    To get the latest features:

    git clone https://github.com/arcee-ai/mergekit.git
    

    cd mergekit

    pip install -e .

    If you want to use the evolution feature (evolutionary merge):

    pip install -e ".[evolve]"
    

    Verify Installation

    mergekit-yaml --help
    

    If this command displays help options, the installation was successful.

    Core Concepts of Model Merging

    Supported Architectures

    MergeKit supports transformer-based models, including:

    • LLaMA and derivatives (Mistral, Qwen, etc.)
    • GPT-NeoX
    • Phi
    • Gemma
    • StableLM
    • And other compatible architectures

    Available Merge Methods

    MergeKit provides several merge methods:

    | Method | Description | When to Use |

    |--------|-------------|-------------|

    | Linear | Simple weighted average of model weights | Baseline, fast, easy to understand |

    | SLERP | Spherical Linear Interpolation | Merging 2 models with smooth transition |

    | TIES | TrIm, Elect, and merGe | Reducing inter-task interference |

    | DARE | Drop And REscale | Similar to TIES with a different approach |

    | Passthrough | Concatenating layers sequentially | Creating larger "frankenmerge" models |

    | Model Stock | Geometric merge in weight space | More robust merging |

    Creating Your First Merge Configuration

    MergeKit uses YAML files to define merge configurations. Let us start with simple examples.

    Linear Merge (Weighted Average)

    Create a file linear-merge.yml:

    mergemethod: linear
    

    dtype: float16

    models:

    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    parameters:

    weight: 0.6

    • model: teknium/OpenHermes-2.5-Mistral-7B
    parameters:

    weight: 0.4

    Run the merge:

    mergekit-yaml linear-merge.yml ./output-linear-merge --cuda --lazy-unpickle
    

    Parameters:

    • --cuda: Use GPU if available (optional, speeds up the process)
    • --lazy-unpickle: Save memory with lazy loading

    SLERP Merge

    SLERP is a very popular method for merging two models. Create a file slerp-merge.yml:

    mergemethod: slerp
    

    dtype: float16

    basemodel: NousResearch/Hermes-2-Pro-Mistral-7B

    parameters:

    t: 0.5

    models:

    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    • model: teknium/OpenHermes-2.5-Mistral-7B

    The t parameter controls interpolation:

    • t: 0.0 = 100% first model
    • t: 0.5 = balanced mixture
    • t: 1.0 = 100% second model

    Run:

    mergekit-yaml slerp-merge.yml ./output-slerp-merge --cuda
    

    TIES Merge

    TIES (TrIm, Elect Sign, and merGe) is effective at reducing inter-task interference. Create a file ties-merge.yml:

    mergemethod: ties
    

    dtype: float16

    basemodel: mistralai/Mistral-7B-v0.1

    parameters:

    density: 0.5

    normalize: true

    models:

    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    parameters:

    weight: 1.0

    density: 0.5

    • model: teknium/OpenHermes-2.5-Mistral-7B
    parameters:

    weight: 0.5

    density: 0.5

    Key TIES parameters:

    • density: Proportion of parameters to keep (0.0-1.0). Lower values mean more parameters are trimmed.
    • normalize: Normalize weights after merging.
    • basemodel: Reference model for computing delta weights.

    mergekit-yaml ties-merge.yml ./output-ties-merge --cuda
    

    DARE Merge

    DARE (Drop And REscale) is similar to TIES but uses random dropping. Create a file dare-merge.yml:

    mergemethod: dareties
    

    dtype: float16

    basemodel: mistralai/Mistral-7B-v0.1

    parameters:

    normalize: true

    models:

    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    parameters:

    weight: 1.0

    density: 0.6

    • model: teknium/OpenHermes-2.5-Mistral-7B
    parameters:

    weight: 0.5

    density: 0.6

    mergekit-yaml dare-merge.yml ./output-dare-merge --cuda
    

    Advanced Usage

    Frankenmerge (Passthrough)

    Frankenmerge allows us to combine layers from different models sequentially, creating a larger model. Create a file franken-merge.yml:

    mergemethod: passthrough
    

    dtype: float16

    slices:

    • sources:
    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    layerrange: [0, 16]

    • sources:
    • model: teknium/OpenHermes-2.5-Mistral-7B
    layer
    range: [8, 24]

    • sources:
    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    layerrange: [16, 32]

    The configuration above takes layers 0-15 from the first model, layers 8-23 from the second model, and layers 16-31 from the first model again, resulting in a model with 48 layers (larger than either source).

    mergekit-yaml franken-merge.yml ./output-franken-merge --cuda
    

    Per-Layer Configuration with Gradients

    We can set different weights per layer using gradients:

    mergemethod: slerp
    

    dtype: float16

    basemodel: NousResearch/Hermes-2-Pro-Mistral-7B

    parameters:

    t:

    • filter: selfattn
    value: [0.0, 0.3, 0.5, 0.7, 1.0]

    • filter: mlp
    value: [1.0, 0.7, 0.5, 0.3, 0.0]

    • value: 0.5
    models:

    • model: NousResearch/Hermes-2-Pro-Mistral-7B
    • model: teknium/OpenHermes-2.5-Mistral-7B

    This configuration uses different gradients for attention layers and MLP layers, providing granular control over the merge process.

    Merge with Custom Tokenizer

    If the models being merged have different tokenizers:

    mergemethod: linear
    

    dtype: float16

    tokenizersource: union

    models:

    • model: modelA
    parameters:

    weight: 0.5

    • model: modelB
    parameters:

    weight: 0.5

    tokenizersource options:
    • union: Combine vocabulary from all models
    • base: Use the base model's tokenizer
    • model:: Use a specific model's tokenizer

    Using Local Models

    You do not have to download from Hugging Face. Local models can also be used:

    mergemethod: slerp
    

    dtype: float16

    basemodel: /path/to/local/model-a

    parameters:

    t: 0.5

    models:

    • model: /path/to/local/model-a
    • model: /path/to/local/model-b

    Evaluating Merged Models

    After merging, it is important to evaluate the results. Here are several approaches:

    Quick Test with Transformers

    from transformers import AutoModelForCausalLM, AutoTokenizer
    
    

    modelpath = "./output-slerp-merge"

    tokenizer = AutoTokenizer.frompretrained(modelpath)

    model = AutoModelForCausalLM.frompretrained(

    modelpath,

    torchdtype="auto",

    devicemap="auto"

    )

    prompt = "Explain machine learning in 3 sentences:"

    inputs = tokenizer(prompt, returntensors="pt").to(model.device)

    outputs = model.generate(inputs, maxnewtokens=200, temperature=0.7)

    print(tokenizer.decode(outputs[0], skipspecialtokens=True))

    Benchmarking with lm-eval

    pip install lm-eval
    
    

    lmeval --model hf \

    --modelargs pretrained=./output-slerp-merge \

    --tasks hellaswag,arceasy,mmlu \

    --batchsize 8

    Output Comparison

    A simple script to compare outputs from the original and merged models:

    from transformers import AutoModelForCausalLM, AutoTokenizer
    

    import torch

    def generateresponse(modelpath, prompt, maxtokens=200):

    tokenizer = AutoTokenizer.frompretrained(modelpath)

    model = AutoModelForCausalLM.frompretrained(

    modelpath, torchdtype=torch.float16, devicemap="auto"

    )

    inputs = tokenizer(prompt, returntensors="pt").to(model.device)

    outputs = model.generate(inputs, maxnewtokens=maxtokens, temperature=0.7)

    return tokenizer.decode(outputs[0], skipspecialtokens=True)

    testprompts = [

    "Write a Python function to calculate fibonacci numbers:",

    "Explain quantum computing to a 5-year-old:",

    "What are the best practices for database indexing?",

    ]

    models = {

    "Model A": "NousResearch/Hermes-2-Pro-Mistral-7B",

    "Merged": "./output-slerp-merge",

    }

    for prompt in testprompts:

    print(f"\nPrompt: {prompt}")

    print("=" * 60)

    for name, path in models.items():

    response = generateresponse(path, prompt)

    print(f"\n[{name}]:")

    print(response)

    Uploading to Hugging Face Hub

    Once you are satisfied with the merge result, upload it to Hugging Face:

    from huggingfacehub import HfApi
    
    

    api = HfApi()

    api.createrepo(

    repoid="username/my-merged-model",

    repotype="model",

    private=False

    )

    api.uploadfolder(

    folderpath="./output-slerp-merge",

    repoid="username/my-merged-model",

    repotype="model",

    )

    Or using the CLI:

    huggingface-cli upload username/my-merged-model ./output-slerp-merge
    

    Remember to create a Model Card (README.md) that explains:

    • Source models used
    • Merge method and parameters
    • Evaluation results
    • Applicable licenses

    Converting to GGUF Format

    To run the merged model in llama.cpp or Ollama, convert it to GGUF:

    git clone https://github.com/ggerganov/llama.cpp.git
    

    cd llama.cpp

    python converthftogguf.py ../output-slerp-merge --outfile merged-model.gguf --outtype f16

    For quantization (reducing file size):

    ./llama-quantize merged-model.gguf merged-model-Q4KM.gguf Q4KM
    

    Popular quantization levels:

    • Q4KM: Balance between size and quality (recommended)
    • Q5KM: Higher quality, larger file
    • Q80: Quality nearly equivalent to fp16, large file

    Best Practices

    1. Choose the Right Source Models

    • Use models with the same architecture (e.g., all Mistral 7B-based)
    • Ensure models use the same or compatible tokenizers
    • Select models fine-tuned for different tasks so they complement each other

    2. Experiment with Parameters

    • Start with SLERP t: 0.5 as a baseline
    • For TIES/DARE, try various density values (0.3, 0.5, 0.7)
    • Use per-layer gradients for finer control
    • Document every experiment along with its results

    3. Resource Management

    • Monitor RAM usage during the merge process
    • Use --lazy-unpickle to reduce memory consumption
    • Use --low-cpu-memory if RAM is limited
    • Store models in safetensors format for safety and speed

    4. Thorough Evaluation

    • Do not rely on a single benchmark
    • Test with prompts relevant to your use case
    • Compare with source models to ensure no regression
    • Check coherence and consistency of outputs

    5. Documentation

    • Create well-documented YAML configs
    • Save all experiment configurations
    • Record source models, methods, parameters, and evaluation results

    Troubleshooting

    Error: Out of Memory

    RuntimeError: CUDA out of memory
    

    Solutions:

    • Run on CPU (remove the --cuda flag)
    • Use --lazy-unpickle
    • Use --low-cpu-memory
    • Merge in a smaller dtype (bfloat16 or float16)

    Error: Incompatible Architecture

    RuntimeError: Incompatible architectures
    

    Solutions:

    • Ensure all models use the same architecture
    • Verify that layer counts and hidden sizes match (except for passthrough merge)

    Error: Tokenizer Mismatch

    If models have different vocabularies, use tokenizersource: union or select a tokenizer from one of the models.

    Conclusion

    MergeKit is an incredibly useful toolkit for creating custom LLM models without any training. By understanding the various merge methods and available parameters, you can experiment and find the optimal combination for your specific needs.

    Key takeaways:

    • Start with simple methods (linear or SLERP) before trying more complex ones
    • Always evaluate merged models thoroughly
    • Document every experiment for reproducibility
    • The best merged models typically combine models that excel in different areas

    With model merging techniques and MergeKit, you can create AI models tailored to your needs without expensive training costs. Happy experimenting!

    Related Articles

    Semantic Router Tutorial: Smart Routing for LLM Applications

    Tutorial Semantic Router: Routing Cerdas untuk Aplikasi LLM Semantic Router adalah library Python yang memungkinkan Anda...

    Complete Unstructured Tutorial: Document Preprocessing for RAG and LLM Applications

    Tutorial Lengkap Unstructured: Preprocessing Dokumen untuk RAG dan Aplikasi LLM Dalam membangun aplikasi Retrieval-Augme...

    Complete Llama Stack Tutorial: Meta's Official Framework for Building AI Applications with Llama Models

    Tutorial Lengkap Llama Stack: Framework Resmi Meta untuk Membangun Aplikasi AI dengan Model Llama Llama Stack adalah fra...

    CAMEL-AI Tutorial: Building Multi-Agent Systems with Communicative AI Agents

    Tutorial Lengkap CAMEL-AI: Framework Multi-Agent Communication untuk Membangun Sistem AI Kolaboratif Penulis: Ruby Abdul...