add the docs and update README for KSFT
409
KT-SFT/README.md
|
|
@ -1,199 +1,294 @@
|
|||
<div align="center">
|
||||
<!-- <h1>KTransformers</h1> -->
|
||||
<p align="center">
|
||||
- [KTransformers Fine-Tuning × LLaMA-Factory Integration – User Guide](#ktransformers-fine-tuning-x-llama-factory-integration-–-user-guide)
|
||||
- [Introduction](#introduction)
|
||||
|
||||
<picture>
|
||||
<img alt="KTransformers" src="https://github.com/user-attachments/assets/d5a2492f-a415-4456-af99-4ab102f13f8b" width=50%>
|
||||
- [Fine-Tuning Results (Examples)](#fine-tuning-results-examples)
|
||||
- [Stylized Dialogue (CatGirl tone)](#stylized-dialogue-catgirl-tone)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Translational-Style dataset](#translational-style-dataset)
|
||||
- [AfriMed-QA (short answer)](#afrimed-qa-short-answer)
|
||||
- [AfriMed-QA (multiple choice)](#afrimed-qa-multiple-choice)
|
||||
|
||||
</picture>
|
||||
- [Quick to Start](#quick-to-start)
|
||||
- [Environment Setup](#environment-setup)
|
||||
- [Core Feature 1: Use KTransformers backend to fine-tune ultra-large MoE models](#core-feature-1-use-ktransformers-backend-to-fine-tune-ultra-large-moe-models)
|
||||
- [Core Feature 2: Chat with the fine-tuned model (base + LoRA adapter)](#core-feature-2-chat-with-the-fine-tuned-model-base--lora-adapter)
|
||||
- [Core Feature 3: Batch inference + metrics (base + LoRA adapter)](#core-feature-3-batch-inference--metrics-base--lora-adapter)
|
||||
|
||||
</p>
|
||||
<h3>A Flexible Framework for Experiencing Cutting-edge LLM Inference Optimizations</h3>
|
||||
<strong><a href="#show-cases">🌟 Show Cases</a> | <a href="#quick-start">🚀 Quick Start</a> | <a href="#tutorial">📃 Tutorial</a> | <a href="https://github.com/kvcache-ai/ktransformers/discussions">💬 Discussion </a>|<a href="#FAQ"> 🙋 FAQ</a> </strong>
|
||||
</div>
|
||||
- [KT Fine-Tuning Speed (User-Side View)](#kt-fine-tuning-speed-user-side-view)
|
||||
- [End-to-End Performance](#end-to-end-performance)
|
||||
- [GPU/CPU Memory Footprint](#gpucpu-memory-footprint)
|
||||
|
||||
<h2 id="intro">🎉 Introduction</h2>
|
||||
KTransformers, pronounced as Quick Transformers, is designed to enhance your 🤗 <a href="https://github.com/huggingface/transformers">Transformers</a> experience with advanced kernel optimizations and placement/parallelism strategies.
|
||||
<br/><br/>
|
||||
KTransformers is a flexible, Python-centric framework designed with extensibility at its core.
|
||||
By implementing and injecting an optimized module with a single line of code, users gain access to a Transformers-compatible
|
||||
interface, RESTful APIs compliant with OpenAI and Ollama, and even a simplified ChatGPT-like web UI.
|
||||
<br/><br/>
|
||||
Our vision for KTransformers is to serve as a flexible platform for experimenting with innovative LLM inference optimizations. Please let us know if you need any other features.
|
||||
- [Conclusion](#conclusion)
|
||||
|
||||
<h2 id="Updates">🔥 Updates</h2>
|
||||
|
||||
* **May 14, 2025**: Support Intel Arc GPU ([Tutorial](./doc/en/xpu.md)).
|
||||
# KTransformers Fine-Tuning × LLaMA-Factory Integration – User Guide
|
||||
|
||||
* **Apr 29, 2025**: Support AMX-Int8、 AMX-BF16 and Qwen3MoE ([Tutorial](./doc/en/AMX.md))
|
||||
**MadSys Lab, KVCache-AI Team, Approaching AI, LLaMA-Factory Team**
|
||||
|
||||
https://github.com/user-attachments/assets/fafe8aec-4e22-49a8-8553-59fb5c6b00a2
|
||||
## Introduction
|
||||
|
||||
From **DeepSeek-V3/R1** to **Qwen3-MoE** and **Kimi-K2**, each wave of open-sourced large models brings leaps in performance and scale. However, many researchers and developers are constrained by expensive GPUs and models with tens or even hundreds of billions of parameters, making it **hard to fine-tune very large models under limited resources**. To bridge this gap, we propose a practical approach: combining **KTransformers** with **LLaMA-Factory**. With just **2–4 RTX 4090s** and a high-memory CPU, you can fine-tune ultra-large MoE models like DeepSeek-671B.
|
||||
|
||||
Our goal is to give resource-constrained researchers a **local path to explore fine-tuning ultra-large models**, and also a fast way to customize smaller models (e.g., 14B/30B) for specific scenarios. We validate the setup using **stylized dialogue**, **Westernized translation tone**, and **medical Q&A** as representative tasks, showing that **personalized adaptation can be achieved within hours**.
|
||||
|
||||
As shown below, LLaMA-Factory is the unified orchestration/configuration layer for the whole fine-tuning workflow—handling data, training scheduling, LoRA injection, and inference interfaces. **KTransformers** acts as a pluggable high-performance backend that takes over core operators like Attention/MoE under the same training configs, enabling efficient **GPU+CPU heterogeneous cooperation**.
|
||||
|
||||

|
||||
|
||||
Within LLaMA-Factory, we compared LoRA fine-tuning with **HuggingFace**, **Unsloth**, and **KTransformers** backends. KTransformers is the **only workable 4090-class solution** for ultra-large MoE models (e.g., 671B) and also delivers higher throughput and lower GPU memory on smaller MoE models (e.g., DeepSeek-14B).
|
||||
|
||||
| Under LoRA (BF16) + [NekoQA-10K stylized dialogue](https://github.com/mindsRiverPonder/LLM-practice) | HuggingFace Backend | Unsloth Backend | KTransformers Backend |
|
||||
| ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------ | --------------------- |
|
||||
| [14B-DeepSeekV2-Lite] LoRA fine-tuning throughput | 303.58 token/s | 455.37 token/s | 530.38 token/s |
|
||||
| [14B-DeepSeekV2-Lite] GPU memory | 32.12 GB | 9.64 GB | 6.08 GB |
|
||||
| [671B-DeepSeekV3] LoRA fine-tuning throughput | <font color='red'>Too Huge to run</font> | <font color='red'>NOT SUPPORT</font> | 40.35 token/s |
|
||||
| [671B-DeepSeekV3] GPU memory (sum across GPUs) | theoretical 1400 GB † | <font color='red'>NOT SUPPORT</font> | 70 GB † |
|
||||
|
||||
† **1400 GB** is a **theoretical** FP16 full-parameter resident footprint (not runnable). **70 GB** is the **measured peak** with KT strategy (Attention on GPU + layered MoE offload).
|
||||
|
||||

|
||||
|
||||
### Fine-Tuning Results (Examples)
|
||||
|
||||
#### Stylized Dialogue (CatGirl tone)
|
||||
|
||||
Dataset: [NekoQA-10K](https://zhuanlan.zhihu.com/p/1934983798233231689). Goal: improve style consistency and recognizability.
|
||||
|
||||
The figure compares responses from the base vs. fine-tuned models. The fine-tuned model maintains the target tone and address terms more consistently (red boxes), validating the effectiveness of **style-transfer fine-tuning**.
|
||||
|
||||

|
||||
|
||||
#### Benchmarks
|
||||
|
||||
We use:
|
||||
|
||||
(1) [Translational-Style-ChatLLM](https://github.com/Benson114/Translational-Style-ChatLLM), which asks for an exaggerated, Westernized translation tone—clear, stylized customization.
|
||||
|
||||
(2) [AfriMed-QA](https://aclanthology.org/2025.acl-long.96/) (ACL 2025), a medical dataset for African contexts with strong domain specificity, including multiple-choice and short-answer sub-tasks—well-suited for vertical fine-tuning evaluation.
|
||||
|
||||
The tables show metrics before vs. after LoRA fine-tuning. We observe **large improvements** across metrics, verifying fine-tuning effectiveness:
|
||||
|
||||
| Translational-Style dataset | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.41** | **22.44** | **15.42** | **11.18** | **42.03** | **18.38** | **33.10** |
|
||||
| V3 base (no LoRA) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
|
||||
| **KT-LoRA fine-tuned V3** | **37.02** | **23.70** | **16.21** | **11.49** | **43.43** | **18.96** | **34.54** |
|
||||
|
||||
| AfriMed-QA (short answer) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.90** | **27.63** | **22.99** | **19.15** | **35.25** | **17.50** | **28.44** |
|
||||
| V3 base (no LoRA) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
|
||||
| **KT-LoRA fine-tuned V3** | **42.42** | **34.12** | **28.95** | **24.54** | **41.97** | **22.37** | **33.28** |
|
||||
|
||||
| AfriMed-QA (multiple choice) | Accuracy |
|
||||
| ------------------------------ | ---------- |
|
||||
| V2-Lite (no LoRA) | 0.0645 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **0.4812** |
|
||||
| V3 base (no LoRA) | 0.5833 |
|
||||
| **KT-LoRA fine-tuned V3** | **0.7930** |
|
||||
|
||||
Even for ultra-large MoE models, **KTransformers-backed fine-tuning** achieves strong task performance quickly.
|
||||
|
||||
|
||||
|
||||
## Quick to Start
|
||||
|
||||
* **Apr 9, 2025**: Experimental support for LLaMA 4 models ([Tutorial](./doc/en/llama4.md)).
|
||||
* **Apr 2, 2025**: Support Multi-concurrency. ([Tutorial](./doc/en/balance-serve.md)).
|
||||
This section shows how to install and use **LLaMA-Factory + KTransformers** for fine-tuning and inference:
|
||||
|
||||
https://github.com/user-attachments/assets/faa3bda2-928b-45a7-b44f-21e12ec84b8a
|
||||
- Environment setup
|
||||
- Fine-tune ultra-large MoE models with KTransformers backend
|
||||
- Load the fine-tuned model (base + LoRA adapter) for chat/inference
|
||||
- Batch inference and metric evaluation
|
||||
|
||||
* **Mar 15, 2025**: Support ROCm on AMD GPU ([Tutorial](./doc/en/ROCm.md)).
|
||||
* **Mar 5, 2025**: Support unsloth 1.58/2.51 bits weights and [IQ1_S/FP8 hybrid](./doc/en/fp8_kernel.md) weights. Support 139K [Longer Context](./doc/en/DeepseekR1_V3_tutorial.md#v022--v023-longer-context--fp8-kernel) for DeepSeek-V3 and R1 in 24GB VRAM.
|
||||
* **Feb 25, 2025**: Support [FP8 GPU kernel](./doc/en/fp8_kernel.md) for DeepSeek-V3 and R1; [Longer Context](./doc/en/DeepseekR1_V3_tutorial.md#v022-longer-context).
|
||||
* **Feb 15, 2025**: Longer Context (from 4K to 8K for 24GB VRAM) & Slightly Faster Speed (+15%, up to 16 Tokens/s), update [docs](./doc/en/DeepseekR1_V3_tutorial.md) and [online books](https://kvcache-ai.github.io/ktransformers/).
|
||||
* **Feb 10, 2025**: Support Deepseek-R1 and V3 on single (24GB VRAM)/multi gpu and 382G DRAM, up to 3~28x speedup. For detailed show case and reproduction tutorial, see [here](./doc/en/DeepseekR1_V3_tutorial.md).
|
||||
* **Aug 28, 2024**: Decrease DeepseekV2's required VRAM from 21G to 11G.
|
||||
* **Aug 15, 2024**: Update detailed [tutorial](doc/en/injection_tutorial.md) for injection and multi-GPU.
|
||||
* **Aug 14, 2024**: Support llamfile as linear backend.
|
||||
* **Aug 12, 2024**: Support multiple GPU; Support new model: mixtral 8\*7B and 8\*22B; Support q2k, q3k, q5k dequant on gpu.
|
||||
* **Aug 9, 2024**: Support windows native.
|
||||
### Environment Setup
|
||||
|
||||
<!-- * **Aug 28, 2024**: Support 1M context under the InternLM2.5-7B-Chat-1M model, utilizing 24GB of VRAM and 150GB of DRAM. The detailed tutorial is [here](./doc/en/long_context_tutorial.md). -->
|
||||
According to the following example, install both the **KTransformers** and **LLaMA-Factory** environments simultaneously.
|
||||
This time, to simplify the installation process of KTransformers, we have specially packaged a wheel file to avoid local compilation.
|
||||
The detailed installation steps are as follows:
|
||||
(Note: Make sure your local **Python version**, **Torch version**, **CUDA version**, and the **KTransformers wheel filename** correspond correctly.)
|
||||
|
||||
<h2 id="show-cases">🌟 Show Cases</h2>
|
||||
```shell
|
||||
# 1. Create a conda environment
|
||||
conda create -n Kllama python=3.10 # choose from : [3.10, 3.11, 3.12, 3.13]
|
||||
conda install -y -c conda-forge libstdcxx-ng gcc_impl_linux-64
|
||||
conda install -y -c nvidia/label/cuda-11.8.0 cuda-runtime
|
||||
|
||||
<div>
|
||||
<h3>GPT-4/o1-level Local VSCode Copilot on a Desktop with only 24GB VRAM</h3>
|
||||
</div>
|
||||
# 2. Install the LLaMA-Factory environment
|
||||
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
|
||||
cd LLaMA-Factory
|
||||
pip install -e ".[torch,metrics]" --no-build-isolation
|
||||
|
||||
https://github.com/user-attachments/assets/ebd70bfa-b2c1-4abb-ae3b-296ed38aa285
|
||||
# 3. Install the KTransformers wheel that matches your Torch and Python versions (Note: The CUDA version can differ from that in the wheel filename.)
|
||||
pip install ktransformers-0.4.1+cu128torch28fancy-cp310-cp310-linux_x86_64.whl
|
||||
|
||||
</p>
|
||||
# 4. Install flash-attention, download the corresponding file based on your Python and Torch versions from: https://github.com/Dao-AILab/flash-attention/releases
|
||||
pip install https://github.com/Dao-AILab/flash-attention/releases/download/v2.8.3/flash_attn-2.8.3+cu12torch2.8cxx11abiTRUE-cp310-cp310-linux_x86_64.whl
|
||||
# abi=True/False can find from below
|
||||
# import torch
|
||||
# print(torch._C._GLIBCXX_USE_CXX11_ABI)
|
||||
|
||||
- **[NEW!!!] Local 671B DeepSeek-Coder-V3/R1:** Running its Q4_K_M version using only 14GB VRAM and 382GB DRAM([Tutorial](./doc/en/DeepseekR1_V3_tutorial.md)).
|
||||
|
||||
- Prefill Speed (tokens/s):
|
||||
- KTransformers: 54.21 (32 cores) → 74.362 (dual-socket, 2×32 cores) → 255.26 (optimized AMX-based MoE kernel, V0.3 only) → 286.55 (selectively using 6 experts, V0.3 only)
|
||||
- Compared to 10.31 tokens/s in llama.cpp with 2×32 cores, achieving up to **27.79× speedup**.
|
||||
- Decode Speed (tokens/s):
|
||||
- KTransformers: 8.73 (32 cores) → 11.26 (dual-socket, 2×32 cores) → 13.69 (selectively using 6 experts, V0.3 only)
|
||||
- Compared to 4.51 tokens/s in llama.cpp with 2×32 cores, achieving up to **3.03× speedup**.
|
||||
- Upcoming Open Source Release:
|
||||
- AMX optimizations and selective expert activation will be open-sourced in V0.3.
|
||||
- Currently available only in preview binary distribution, which can be downloaded [here](./doc/en/DeepseekR1_V3_tutorial.md).
|
||||
- **Local 236B DeepSeek-Coder-V2:** Running its Q4_K_M version using only 21GB VRAM and 136GB DRAM, attainable on a local desktop machine, which scores even better than GPT4-0613 in [BigCodeBench](https://huggingface.co/blog/leaderboard-bigcodebench).
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="DeepSeek-Coder-V2 Score" src="https://github.com/user-attachments/assets/d052924e-8631-44de-aad2-97c54b965693" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
- **Faster Speed:** Achieving 126 tokens/s for 2K prompt prefill and 13.6 tokens/s for generation through MoE offloading and injecting advanced kernels from [Llamafile](https://github.com/Mozilla-Ocho/llamafile/tree/main) and [Marlin](https://github.com/IST-DASLab/marlin).
|
||||
- **VSCode Integration:** Wrapped into an OpenAI and Ollama compatible API for seamless integration as a backend for [Tabby](https://github.com/TabbyML/tabby) and various other frontends.
|
||||
|
||||
<p align="center">
|
||||
|
||||
https://github.com/user-attachments/assets/4c6a8a38-05aa-497d-8eb1-3a5b3918429c
|
||||
|
||||
</p>
|
||||
|
||||
<!-- <h3>1M Context Local Inference on a Desktop with Only 24GB VRAM</h3>
|
||||
<p align="center">
|
||||
|
||||
https://github.com/user-attachments/assets/a865e5e4-bca3-401e-94b8-af3c080e6c12
|
||||
|
||||
* **1M Context InternLM 2.5 7B**: Operates at full bf16 precision, utilizing 24GB VRAM and 150GB DRAM, which is feasible on a local desktop setup. It achieves a 92.88% success rate on the 1M "Needle In a Haystack" test and 100% on the 128K NIAH test.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Single Needle Retrieval 128K" src="./doc/assets/needle_128K.png" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Single Needle Retrieval 1000K" src="./doc/assets/needle_1M.png" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
* **Enhanced Speed**: Reaches 16.91 tokens/s for generation with a 1M context using sparse attention, powered by llamafile kernels. This method is over 10 times faster than full attention approach of llama.cpp.
|
||||
|
||||
* **Flexible Sparse Attention Framework**: Offers a flexible block sparse attention framework for CPU offloaded decoding. Compatible with SnapKV, Quest, and InfLLm. Further information is available [here](./doc/en/long_context_introduction.md).
|
||||
-->
|
||||
|
||||
<strong>More advanced features will coming soon, so stay tuned!</strong>
|
||||
|
||||
<h2 id="quick-start">🚀 Quick Start</h2>
|
||||
|
||||
Getting started with KTransformers is simple! Follow the steps below to set up and start using it.
|
||||
|
||||
we have already supported vendors:
|
||||
|
||||
- Metax
|
||||
- Sanechips (ZhuFeng V1.0)
|
||||
- Intel
|
||||
- Ascend
|
||||
- Kunpeng
|
||||
- AMD
|
||||
|
||||
|
||||
### 📥 Installation
|
||||
|
||||
To install KTransformers, follow the official [Installation Guide](https://kvcache-ai.github.io/ktransformers/en/install.html).
|
||||
|
||||
<h2 id="tutorial">📃 Brief Injection Tutorial</h2>
|
||||
At the heart of KTransformers is a user-friendly, template-based injection framework.
|
||||
This allows researchers to easily replace original torch modules with optimized variants. It also simplifies the process of combining multiple optimizations, allowing the exploration of their synergistic effects.
|
||||
|
||||
</br>
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="https://github.com/user-attachments/assets/6b4c1e54-9f6d-45c5-a3fc-8fa45e7d257e" width=65%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
Given that vLLM already serves as a great framework for large-scale deployment optimizations, KTransformers is particularly focused on local deployments that are constrained by limited resources. We pay special attention to heterogeneous computing opportunities, such as GPU/CPU offloading of quantized models. For example, we support the efficient <a herf="https://github.com/Mozilla-Ocho/llamafile/tree/main">Llamafile</a> and <a herf="https://github.com/IST-DASLab/marlin">Marlin</a> kernels for CPU and GPU, respectively. More details can be found <a herf="doc/en/operators/llamafile.md">here</a>.
|
||||
|
||||
<h3>Example Usage</h3>
|
||||
To utilize the provided kernels, users only need to create a YAML-based injection template and add the call to `optimize_and_load_gguf` before using the Transformers model.
|
||||
|
||||
```python
|
||||
with torch.device("meta"):
|
||||
model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
|
||||
optimize_and_load_gguf(model, optimize_config_path, gguf_path, config)
|
||||
...
|
||||
generated = prefill_and_generate(model, tokenizer, input_tensor.cuda(), max_new_tokens=1000)
|
||||
# 5. (Optional) If you want to use flash_infer (otherwise it defaults to triton)
|
||||
git clone https://github.com/kvcache-ai/custom_flashinfer.git
|
||||
pip install custom_flashinfer/
|
||||
```
|
||||
|
||||
In this example, the AutoModel is first initialized on the meta device to avoid occupying any memory resources. Then, `optimize_and_load_gguf` iterates through all sub-modules of the model, matches rules specified in your YAML rule file, and replaces them with advanced modules as specified.
|
||||
**Usage tip:** In LLaMA-Factory YAML, set `use_kt: true` and pick a `kt_optimize_rule` file to have KTransformers handle the core compute. The features below show typical configs.
|
||||
|
||||
After injection, the original `generate` interface is available, but we also provide a compatible `prefill_and_generate` method, which enables further optimizations like CUDAGraph to improve generation speed.
|
||||
### Core Feature 1: Use KTransformers backend to fine-tune ultra-large MoE models
|
||||
|
||||
<h3>How to custom your model</h3>
|
||||
Run the command: `USE_KT=1 llamafactory-cli train examples/train_lora/deepseek3_lora_sft_kt.yaml`.
|
||||
|
||||
A detailed tutorial of the injection and multi-GPU using DeepSeek-V2 as an example is given [here](doc/en/injection_tutorial.md).
|
||||
Note: You **must** provide a **BF16** model. DeepSeek-V3-671B is released in FP8 by default; convert with [DeepSeek-V3/inference/fp8_cast_bf16.py](https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/fp8_cast_bf16.py).
|
||||
|
||||
Below is an example of a YAML template for replacing all original Linear modules with Marlin, an advanced 4-bit quantization kernel.
|
||||
```yaml
|
||||
### model
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
trust_remote_code: true
|
||||
|
||||
### method
|
||||
stage: sft
|
||||
do_train: true
|
||||
finetuning_type: lora
|
||||
lora_rank: 8
|
||||
lora_target: all
|
||||
|
||||
### dataset
|
||||
dataset: identity
|
||||
template: deepseek
|
||||
cutoff_len: 2048
|
||||
max_samples: 100000
|
||||
overwrite_cache: true
|
||||
preprocessing_num_workers: 16
|
||||
dataloader_num_workers: 4
|
||||
|
||||
### output
|
||||
output_dir: saves/Kllama_deepseekV3
|
||||
logging_steps: 10
|
||||
save_steps: 500
|
||||
plot_loss: true
|
||||
overwrite_output_dir: true
|
||||
save_only_model: false
|
||||
report_to: none # choices: [none, wandb, tensorboard, swanlab, mlflow]
|
||||
|
||||
### train
|
||||
per_device_train_batch_size: 1
|
||||
gradient_accumulation_steps: 8
|
||||
learning_rate: 1.0e-4
|
||||
num_train_epochs: 3.0
|
||||
lr_scheduler_type: cosine
|
||||
warmup_ratio: 0.1
|
||||
bf16: true
|
||||
ddp_timeout: 180000000
|
||||
resume_from_checkpoint: null
|
||||
|
||||
### ktransformers
|
||||
use_kt: true # use KTransformers as LoRA sft backend
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
`kt_optimize_rule` controls **placement strategy**. See also [ktransformers/optimize_rules](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/optimize/optimize_rules). Naming hints (`*` = wildcard):
|
||||
|
||||
| Pattern | Meaning |
|
||||
| -------------------------------------------- | ----------------------------------------------------- |
|
||||
| DeepSeek-V2-Lite-Chat-* / DeepSeek-V3-Chat-* | Target model variants |
|
||||
| *-sft-* | Strategy for fine-tuning; others are for inference |
|
||||
| *-amx-* | Use AMX on CPU; otherwise use **llamafile** |
|
||||
| *-multi-gpu-X* | Model parallel on X GPUs (X omitted → default 2 GPUs) |
|
||||
|
||||
Example: `DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml` = V3-Chat fine-tuning with AMX and 2-GPU model parallel.
|
||||
|
||||
We recommend **AMX acceleration** where available (`lscpu | grep amx`). AMX supports BF16/INT8. Example:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*$" # regular expression
|
||||
class: torch.nn.Linear # only match modules matching name and class simultaneously
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.linear.KTransformerLinear # optimized Kernel on quantized data types
|
||||
device: "cpu" # which devices to load this module when initializing
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert parallelism
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
generate_linear_type: "QuantizedLinearMarlin"
|
||||
prefill_device: "cpu"
|
||||
prefill_op: "KExpertsTorch"
|
||||
generate_device: "cpu"
|
||||
generate_op: "KSFTExpertsCPU"
|
||||
out_device: "cuda"
|
||||
backend: "AMXInt8" # or "AMXBF16" or "llamafile" (default)
|
||||
```
|
||||
|
||||
Each rule in the YAML file has two parts: `match` and `replace`. The `match` part specifies which module should be replaced, and the `replace` part specifies the module to be injected into the model along with the initialization keywords.
|
||||
Outputs go to `output_dir` in safetensors format plus adapter metadata for later loading.
|
||||
|
||||
You can find example rule templates for optimizing DeepSeek-V2 and Qwen2-57B-A14, two SOTA MoE models, in the [ktransformers/optimize/optimize_rules](ktransformers/optimize/optimize_rules) directory. These templates are used to power the `local_chat.py` demo.
|
||||

|
||||
|
||||
If you are interested in our design principles and the implementation of the injection framework, please refer to the [design document](doc/en/deepseek-v2-injection.md).
|
||||
### Core Feature 2: Chat with the fine-tuned model (base + LoRA adapter)
|
||||
|
||||
<h2 id="ack">Acknowledgment and Contributors</h2>
|
||||
Run the command: `llamafactory-cli chat examples/inference/deepseek3_lora_sft_kt.yaml`.
|
||||
|
||||
The development of KTransformers is based on the flexible and versatile framework provided by Transformers. We also benefit from advanced kernels such as GGUF/GGML, Llamafile, Marlin, sglang and flashinfer. We are planning to contribute back to the community by upstreaming our modifications.
|
||||
Use the safetensors adapter trained with KT for inference.
|
||||
|
||||
KTransformers is actively maintained and developed by contributors from the <a href="https://madsys.cs.tsinghua.edu.cn/">MADSys group</a> at Tsinghua University and members from <a href="http://approaching.ai/">Approaching.AI</a>. We welcome new contributors to join us in making KTransformers faster and easier to use.
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
<h2 id="ack">Discussion</h2>
|
||||
use_kt: true # use KTransformers as LoRA sft backend to inference
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
If you have any questions, feel free to open an issue. Alternatively, you can join our WeChat group for further discussion. QR Code: [WeChat Group](WeChatGroup.png)
|
||||
We also support **GGUF** adapters: for safetensors, set the **directory**; for GGUF, set the **file path** in `adapter_name_or_path`.
|
||||
|
||||
<h2 id="FAQ">🙋 FAQ</h2>
|
||||
During loading, LLaMA-Factory maps layer names to KT’s naming. You’ll see logs like `Loaded adapter weight: XXX -> XXX`:
|
||||
|
||||
Some common questions are answered in the [FAQ](doc/en/FAQ.md).
|
||||

|
||||
|
||||
### Core Feature 3: Batch inference + metrics (base + LoRA adapter)
|
||||
|
||||
Run the command: `API_PORT=8000 llamafactory-cli api examples/inference/deepseek3_lora_sft_kt.yaml`.
|
||||
Invoke the KT fine-tuned adapter to provide the API; the usage logic of other APIs is consistent with the native LLaMA-Factory approach.
|
||||
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
use_kt: true # use KTransformers as LoRA sft backend to inference
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
|
||||
|
||||
## KT Fine-Tuning Speed (User-Side View)
|
||||
|
||||
### End-to-End Performance
|
||||
|
||||
**Definitions**
|
||||
|
||||
- `step_time`: wall-clock time for a full optimization step (tensor movement + Attention + MoE + other compute).
|
||||
- `tokens_per_step = GAS × qlen`; `token/s = tokens_per_step / step_time`.
|
||||
|
||||
**Settings:** `GAS=16`, `qlen=512` (→ `tokens_per_step = 8192`); LoRA (`r=8, alpha=32, dropout=0.1`); **AMX** enabled; GPU: RTX 4090, CPU: Intel Xeon Platinum 8488C.
|
||||
|
||||
**Measured**
|
||||
|
||||
- **DeepSeek-V3-671B:** `step_time = 203 s` → `token/s ≈ 8192 / 203 ≈ 40.35`
|
||||
- **DeepSeek-V2-Lite-14B:** `step_time = 36 s` → `token/s ≈ 8192 / 36 ≈ 227.6`
|
||||
|
||||
### GPU/CPU Memory Footprint
|
||||
|
||||
- DeepSeek-V3 (671B; 61 layers with 58 MoE): ~**70 GB** total GPU memory (multi-GPU), ~**1.2–1.3 TB** host memory.
|
||||
- DeepSeek-V2-Lite (14B; 27 layers with 26 MoE): ~**5.5 GB** GPU memory, ~**150 GB** host memory.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By integrating **KTransformers LoRA fine-tuning** into **LLaMA-Factory**, we provide a practical guide for efficient training and deployment of MoE LLMs. KT brings cutting-edge optimizations (DeepSeek/Qwen/Kimi support with AMX-accelerated kernels), and LoRA enables customization under very low GPU memory. LLaMA-Factory offers a friendly, unified interface.
|
||||
|
||||
This integration (akin to Unsloth-style speedups) means even models with tens to hundreds of billions of parameters can be fine-tuned and deployed with low latency on commodity hardware. You get **memory savings, speed-ups, and usability** together. We encourage you to try LLaMA-Factory + KT for your next MoE project and follow this guide. Feedback is welcome!
|
||||
|
|
@ -1,166 +0,0 @@
|
|||
<div align="center">
|
||||
<!-- <h1>KTransformers</h1> -->
|
||||
<p align="center">
|
||||
|
||||
<picture>
|
||||
<img alt="KTransformers" src="https://github.com/user-attachments/assets/d5a2492f-a415-4456-af99-4ab102f13f8b" width=50%>
|
||||
|
||||
</picture>
|
||||
|
||||
</p>
|
||||
<h3>一个用于体验尖端 LLM 推理优化的灵活框架</h3>
|
||||
<strong><a href="#show-cases">🌟 案例展示</a> | <a href="#quick-start">🚀 快速入门</a> | <a href="#tutorial">📃 教程</a> | <a href="https://github.com/kvcache-ai/ktransformers/discussions">💬 讨论</a> | <a href="#FAQ">🙋 常见问题</a> </strong>
|
||||
</div>
|
||||
|
||||
<h2 id="intro">🎉 介绍</h2>
|
||||
KTransformers(发音为 Quick Transformers)旨在通过先进的内核优化和放置/并行策略来增强您对 🤗 [Transformers](https://github.com/huggingface/transformers) 的体验。
|
||||
<br/><br/>
|
||||
KTransformers 是一个以 Python 为中心的灵活框架,其核心是可扩展性。通过用一行代码实现并注入优化模块,用户可以获得与 Transformers 兼容的接口、符合 OpenAI 和 Ollama 的 RESTful API,甚至是一个简化的类似 ChatGPT 的 Web 界面。
|
||||
<br/><br/>
|
||||
我们对 KTransformers 的愿景是成为一个用于实验创新 LLM 推理优化的灵活平台。如果您需要任何其他功能,请告诉我们。
|
||||
|
||||
<h2 id="Updates">🔥 更新</h2>
|
||||
|
||||
* **2025 年 2 月 15 日**:为DeepSeek-V3/R1支持[FP8 GPU内核](./doc/en/fp8_kernel.md); 支持更长的上下文([教程](./doc/en/DeepseekR1_V3_tutorial.md#v022-longer-context)).
|
||||
* **2025 年 2 月 15 日**:长上下文(从4K到8K,24GB VRAM) & 稍快的速度(+15%)(最快 16 Tokens/s),文档请参见 [这里](./doc/en/DeepseekR1_V3_tutorial.md) 和 [在线指南](https://kvcache-ai.github.io/ktransformers/) 。
|
||||
* **2025 年 2 月 10 日**:支持 Deepseek-R1 和 V3 在单个(24GB VRAM)/多 GPU 和 382G DRAM 上运行,速度提升高达 3~28 倍。详细教程请参见 [这里](./doc/en/DeepseekR1_V3_tutorial.md)。
|
||||
* **2024 年 8 月 28 日**:支持 InternLM2.5-7B-Chat-1M 模型下的 1M 上下文,使用 24GB 的 VRAM 和 150GB 的 DRAM。详细教程请参见 [这里](./doc/en/long_context_tutorial.md)。
|
||||
* **2024 年 8 月 28 日**:将 DeepseekV2 所需的 VRAM 从 21G 降低到 11G。
|
||||
* **2024 年 8 月 15 日**:更新了详细的 [教程](doc/en/injection_tutorial.md),介绍注入和多 GPU 的使用。
|
||||
* **2024 年 8 月 14 日**:支持 llamfile 作为线性后端。
|
||||
* **2024 年 8 月 12 日**:支持多 GPU;支持新模型:mixtral 8\*7B 和 8\*22B;支持 q2k、q3k、q5k 在 GPU 上的去量化。
|
||||
* **2024 年 8 月 9 日**:支持 Windows。
|
||||
|
||||
<h2 id="show-cases">🌟 案例展示</h2>
|
||||
|
||||
<div>
|
||||
<h3>在仅 24GB VRAM 的桌面上运行 GPT-4/o1 级别的本地 VSCode Copilot</h3>
|
||||
</div>
|
||||
|
||||
https://github.com/user-attachments/assets/ebd70bfa-b2c1-4abb-ae3b-296ed38aa285
|
||||
|
||||
</p>
|
||||
|
||||
- **[NEW!!!] 本地 671B DeepSeek-Coder-V3/R1**:使用其 Q4_K_M 版本,仅需 14GB VRAM 和 382GB DRAM 即可运行(教程请参见 [这里](./doc/en/DeepseekR1_V3_tutorial.md))。
|
||||
- 预填充速度(tokens/s):
|
||||
- KTransformers:54.21(32 核)→ 74.362(双插槽,2×32 核)→ 255.26(优化的 AMX 基 MoE 内核,仅 V0.3)→ 286.55(选择性使用 6 个专家,仅 V0.3)
|
||||
- 与 llama.cpp 在 2×32 核下相比,达到 **27.79× 速度提升**。
|
||||
- 解码速度(tokens/s):
|
||||
- KTransformers:8.73(32 核)→ 11.26(双插槽,2×32 核)→ 13.69(选择性使用 6 个专家,仅 V0.3)
|
||||
- 与 llama.cpp 在 2×32 核下相比,达到 **3.03× 速度提升**。
|
||||
- 即将开源发布:
|
||||
- AMX 优化和选择性专家激活将在 V0.3 中开源。
|
||||
- 目前仅在预览二进制分发中可用,可从 [这里](./doc/en/DeepseekR1_V3_tutorial.md) 下载。
|
||||
|
||||
- **本地 236B DeepSeek-Coder-V2**:使用其 Q4_K_M 版本,仅需 21GB VRAM 和 136GB DRAM 即可运行,甚至在 [BigCodeBench](https://huggingface.co/blog/leaderboard-bigcodebench) 中得分超过 GPT4-0613。
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="DeepSeek-Coder-V2 Score" src="https://github.com/user-attachments/assets/d052924e-8631-44de-aad2-97c54b965693" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
- **更快的速度**:通过 MoE 卸载和注入来自 [Llamafile](https://github.com/Mozilla-Ocho/llamafile/tree/main) 和 [Marlin](https://github.com/IST-DASLab/marlin) 的高级内核,实现了 2K 提示预填充 126 tokens/s 和生成 13.6 tokens/s 的速度。
|
||||
- **VSCode 集成**:封装成符合 OpenAI 和 Ollama 的 API,可无缝集成到 [Tabby](https://github.com/TabbyML/tabby) 和其他前端的后端。
|
||||
|
||||
<p align="center">
|
||||
|
||||
https://github.com/user-attachments/assets/4c6a8a38-05aa-497d-8eb1-3a5b3918429c
|
||||
|
||||
</p>
|
||||
|
||||
<!-- <h3>在仅 24GB VRAM 的桌面上进行 1M 上下文本地推理</h3>
|
||||
<p align="center"> -->
|
||||
|
||||
<!-- https://github.com/user-attachments/assets/a865e5e4-bca3-401e-94b8-af3c080e6c12 -->
|
||||
<!--
|
||||
* **1M 上下文 InternLM 2.5 7B**:以全 bf16 精度运行,使用 24GB VRAM 和 150GB DRAM,可在本地桌面设置中实现。在 1M "针在干草堆中" 测试中达到 92.88% 的成功率,在 128K NIAH 测试中达到 100%。
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Single Needle Retrieval 128K" src="./doc/assets/needle_128K.png" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Single Needle Retrieval 1000K" src="./doc/assets/needle_1M.png" width=100%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
* **增强的速度**:使用稀疏注意力,通过 llamafile 内核实现 1M 上下文生成 16.91 tokens/s 的速度。这种方法比 llama.cpp 的全注意力方法快 10 倍以上。
|
||||
|
||||
* **灵活的稀疏注意力框架**:提供了一个灵活的块稀疏注意力框架,用于 CPU 卸载解码。与 SnapKV、Quest 和 InfLLm 兼容。更多信息请参见 [这里](./doc/en/long_context_introduction.md)。 -->
|
||||
|
||||
<strong>更多高级功能即将推出,敬请期待!</strong>
|
||||
|
||||
<h2 id="quick-start">🚀 快速入门</h2>
|
||||
|
||||
|
||||
KTransformers 的入门非常简单!请参考我们的[安装指南]((https://kvcache-ai.github.io/ktransformers/))进行安装。
|
||||
|
||||
<h2 id="tutorial">📃 简要注入教程</h2>
|
||||
KTransformers 的核心是一个用户友好的、基于模板的注入框架。这使得研究人员可以轻松地将原始 torch 模块替换为优化的变体。它还简化了多种优化的组合过程,允许探索它们的协同效应。
|
||||
</br>
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="https://github.com/user-attachments/assets/6b4c1e54-9f6d-45c5-a3fc-8fa45e7d257e" width=65%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
鉴于 vLLM 已经是一个用于大规模部署优化的优秀框架,KTransformers 特别关注受资源限制的本地部署。我们特别关注异构计算时机,例如量化模型的 GPU/CPU 卸载。例如,我们支持高效的 <a herf="https://github.com/Mozilla-Ocho/llamafile/tree/main">Llamafile</a> 和<a herf="https://github.com/IST-DASLab/marlin">Marlin</a> 内核,分别用于 CPU 和 GPU。 更多详细信息可以在 <a herf="doc/en/operators/llamafile.md">这里</a>找到。
|
||||
|
||||
|
||||
<h3>示例用法</h3>
|
||||
要使用提供的内核,用户只需创建一个基于 YAML 的注入模板,并在使用 Transformers 模型之前添加对 `optimize_and_load_gguf` 的调用。
|
||||
|
||||
```python
|
||||
with torch.device("meta"):
|
||||
model = AutoModelForCausalLM.from_config(config, trust_remote_code=True)
|
||||
optimize_and_load_gguf(model, optimize_config_path, gguf_path, config)
|
||||
...
|
||||
generated = prefill_and_generate(model, tokenizer, input_tensor.cuda(), max_new_tokens=1000)
|
||||
```
|
||||
|
||||
在这个示例中,首先在 meta 设备上初始化 AutoModel,以避免占用任何内存资源。然后,`optimize_and_load_gguf` 遍历模型的所有子模块,匹配您的 YAML 规则文件中指定的规则,并将它们替换为指定的高级模块。
|
||||
|
||||
注入后,原始的 `generate` 接口仍然可用,但我们还提供了一个兼容的 `prefill_and_generate` 方法,这使得可以进一步优化,例如使用 CUDAGraph 提高生成速度。
|
||||
|
||||
<h3>如何自定义您的模型</h3>
|
||||
|
||||
一个详细的使用 DeepSeek-V2 作为示例的注入和 multi-GPU 教程在 [这里](doc/en/injection_tutorial.md)。
|
||||
|
||||
以下是一个将所有原始 Linear 模块替换为 Marlin 的 YAML 模板示例,Marlin 是一个高级的 4 位量化内核。
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*$" # 正则表达式
|
||||
class: torch.nn.Linear # 仅匹配同时符合名称和类的模块
|
||||
replace:
|
||||
class: ktransformers.operators.linear.KTransformerLinear # 量化数据类型的优化内核
|
||||
device: "cpu" # 初始化时加载该模块的 device
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
generate_linear_type: "QuantizedLinearMarlin"
|
||||
```
|
||||
|
||||
YAML 文件中的每个规则都有两部分:`match` 和 `replace`。`match` 部分指定应替换的模块,`replace` 部分指定要注入到模型中的模块以及初始化关键字。
|
||||
|
||||
您可以在 [ktransformers/optimize/optimize_rules](ktransformers/optimize/optimize_rules) 目录中找到用于优化 DeepSeek-V2 和 Qwen2-57B-A14 的示例规则模板。这些模板用于为 `local_chat.py` 示例提供支持。
|
||||
|
||||
如果您对我们的设计原则和注入框架的实现感兴趣,请参考 [设计文档](doc/en/deepseek-v2-injection.md)。
|
||||
|
||||
<h2 id="ack">致谢和贡献者</h2>
|
||||
|
||||
KTransformers 的开发基于 Transformers 提供的灵活和多功能框架。我们还受益于 GGUF/GGML、Llamafile 、 Marlin、sglang和flashinfer 等高级内核。我们计划通过向上游贡献我们的修改来回馈社区。
|
||||
|
||||
KTransformers 由清华大学 <a href="https://madsys.cs.tsinghua.edu.cn/">MADSys group</a> 小组的成员以及 <a href="http://approaching.ai/">Approaching.AI</a> 的成员积极维护和开发。我们欢迎新的贡献者加入我们,使 KTransformers 更快、更易于使用。
|
||||
|
||||
|
||||
<h2 id="ack">讨论</h2>
|
||||
|
||||
如果您有任何问题,欢迎随时提出 issue。或者,您可以加入我们的微信群进行进一步讨论。二维码: [微信群](WeChatGroup.png)
|
||||
|
||||
<h2 id="FAQ">🙋 常见问题</h2>
|
||||
|
||||
一些常见问题的答案可以在 [FAQ](doc/en/FAQ.md) 中找到。
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
<div align="center">
|
||||
<!-- <h1>KTransformers</h1> -->
|
||||
<p align="center">
|
||||
|
||||
<picture>
|
||||
<img alt="KTransformers" src="https://github.com/user-attachments/assets/d5a2492f-a415-4456-af99-4ab102f13f8b" width=50%>
|
||||
|
||||
</picture>
|
||||
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<h2 id="intro">🎉 Introduction</h2>
|
||||
KTransformers, pronounced as Quick Transformers, is designed to enhance your 🤗 <a href="https://github.com/huggingface/transformers">Transformers</a> experience with advanced kernel optimizations and placement/parallelism strategies.
|
||||
<br/><br/>
|
||||
KTransformers is a flexible, Python-centric framework designed with extensibility at its core.
|
||||
By implementing and injecting an optimized module with a single line of code, users gain access to a Transformers-compatible
|
||||
interface, RESTful APIs compliant with OpenAI and Ollama, and even a simplified ChatGPT-like web UI.
|
||||
<br/><br/>
|
||||
Our vision for KTransformers is to serve as a flexible platform for experimenting with innovative LLM inference optimizations. Please let us know if you need any other features.
|
||||
|
||||
<h2 id="Updates">🔥 Updates</h2>
|
||||
|
||||
* **May 14, 2025**: Support Intel Arc GPU ([Tutorial](./en/xpu.md)).
|
||||
* **Apr 9, 2025**: Experimental support for LLaMA 4 models ([Tutorial](./en/llama4.md)).
|
||||
* **Apr 2, 2025**: Support Multi-concurrency. ([Tutorial](./en/balance-serve.md)).
|
||||
* **Mar 27, 2025**: Support Multi-concurrency.
|
||||
* **Mar 15, 2025**: Support ROCm on AMD GPU ([Tutorial](./en/ROCm.md)).
|
||||
* **Mar 5, 2025**: Support unsloth 1.58/2.51 bits weights and [IQ1_S/FP8 hybrid](./en/fp8_kernel.md) weights. Support 139K [Longer Context](./en/DeepseekR1_V3_tutorial.md#v022-longer-context) for DeepSeek-V3 and R1 in 24GB VRAM.
|
||||
* **Feb 25, 2025**: Support [FP8 GPU kernel](./en/fp8_kernel.md) for DeepSeek-V3 and R1; [Longer Context](./en/DeepseekR1_V3_tutorial.md#v022-longer-context).
|
||||
* **Feb 10, 2025**: Support Deepseek-R1 and V3 on single (24GB VRAM)/multi gpu and 382G DRAM, up to 3~28x speedup. The detailed tutorial is [here](./en/DeepseekR1_V3_tutorial.md).
|
||||
* **Aug 28, 2024**: Support 1M context under the InternLM2.5-7B-Chat-1M model, utilizing 24GB of VRAM and 150GB of DRAM. The detailed tutorial is [here](./en/long_context_tutorial.md).
|
||||
* **Aug 28, 2024**: Decrease DeepseekV2's required VRAM from 21G to 11G.
|
||||
* **Aug 15, 2024**: Update detailed [TUTORIAL](./en/injection_tutorial.md) for injection and multi-GPU.
|
||||
* **Aug 14, 2024**: Support llamfile as linear backend.
|
||||
* **Aug 12, 2024**: Support multiple GPU; Support new model: mixtral 8\*7B and 8\*22B; Support q2k, q3k, q5k dequant on gpu.
|
||||
* **Aug 9, 2024**: Support windows native.
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# Ktransformers
|
||||
|
||||
[Introduction](./README.md)
|
||||
# Install
|
||||
- [Installation Guide](en/install.md)
|
||||
|
||||
# Tutorial
|
||||
- [Deepseek-R1/V3 Show Case/Tutorial](en/DeepseekR1_V3_tutorial.md)
|
||||
- [Why KTransformers So Fast](en/deepseek-v2-injection.md)
|
||||
- [Injection Tutorial](en/injection_tutorial.md)
|
||||
- [Multi-GPU Tutorial](en/multi-gpu-tutorial.md)
|
||||
- [Use FP8 GPU Kernel](en/fp8_kernel.md)
|
||||
- [Use AMD GPU](en/ROCm.md)
|
||||
# Server
|
||||
- [Server](en/api/server/server.md)
|
||||
- [Website](en/api/server/website.md)
|
||||
- [Tabby](en/api/server/tabby.md)
|
||||
# For Developer
|
||||
- [Makefile Usage](en/makefile_usage.md)
|
||||
|
||||
# FAQ
|
||||
- [FAQ](en/FAQ.md)
|
||||
# V3 Reproduction
|
||||
- [Success List](en/V3-success.md)
|
||||
# Benchmark
|
||||
- [Benchmark](en/benchmark.md)
|
||||
|
Before Width: | Height: | Size: 968 KiB |
|
Before Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 312 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 284 KiB |
|
Before Width: | Height: | Size: 209 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 162 KiB |
|
Before Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 125 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
Before Width: | Height: | Size: 147 KiB |
|
Before Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 502 KiB |
|
|
@ -1 +0,0 @@
|
|||
# basic-first20
|
||||
|
|
@ -1 +0,0 @@
|
|||
# basic-data_structure
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
# Qwen 3 + KTransformers 0.3 (+AMX) = AI Workstation/PC
|
||||
Following DeepSeek-V3/R1, LLaMa-4, and Kimi-VL, Qwen has also released an impressive MoE model—undoubtedly, this year belongs to MoE. As a low-barrier inference system for running MoE models in local heterogeneous environments, KTransformers naturally joins the party. Thanks to the support of the Qwen team, we completed Day 0 support for the entire Qwen 3 series of MoE models. At the same time, we took this opportunity to open-source the long-awaited preliminary version of our AMX high-performance operators (BF16, Int8; an int4 variant is coming soon), officially advancing to version 0.3.
|
||||
|
||||
What excites me most about Qwen3MoE is that, unlike the 671 B “giant” model, its two configurations: 235B-A22 and 30B-A3B, **hit the performance sweet spots for both local workstations and consumer-grade PCs**. Accordingly, we ran benchmarks in two typical setups:
|
||||
|
||||
Server CPU (Xeon 4) + RTX 4090
|
||||
|
||||
Consumer-grade CPU (Core i9-14900KF + dual-channel DDR5-4000 MT/s) + RTX 4090
|
||||
|
||||
Note: Because the PC's memory has a low frequency, large capacity, and multiple sticks, it downclocks severely and only operates at 4000MT. Using higher - frequency memory can boost performance.
|
||||
|
||||
The results are as follows:
|
||||
|
||||
https://github.com/user-attachments/assets/fafe8aec-4e22-49a8-8553-59fb5c6b00a2
|
||||
|
||||
|
||||

|
||||
|
||||
You can see that, thanks to the AMX instruction optimizations, we achieve up to 347 tokens/s prefill performance in the workstation scenario. On consumer-grade CPUs, we’re able to run the large model (235B-A22) and deliver smooth performance on the smaller 30B-A3B. Even in terms of resource overhead, it appears that a high-end gaming laptop can handle 30B-A3B smoothly. After talking about the concept of AIPC for so long, we can finally see its feasibility.
|
||||
|
||||
Here is the Qwen3MoE startup command:
|
||||
|
||||
``` python
|
||||
# llamafile backend
|
||||
python ktransformers/server/main.py --architectures Qwen3MoeForCausalLM --model_path <model_dir> --gguf_path <gguf_dir> --optimize_config_path ktransformers/optimize/optimize_rules/Qwen3Moe-serve.yaml --backend_type balance_serve
|
||||
# AMX backend
|
||||
python ktransformers/server/main.py --architectures Qwen3MoeForCausalLM --model_path <model_dir> --gguf_path <gguf_dir> --optimize_config_path ktransformers/optimize/optimize_rules/Qwen3Moe-serve-amx.yaml --backend_type balance_serve
|
||||
```
|
||||
|
||||
**Note: At present, Qwen3MoE running with AMX can only read BF16 GGUF; support for loading from safetensor will be added later.**
|
||||
|
||||
To make it easier for everyone to understand the AMX optimizations we’ve open-sourced, we’ve prepared a brief document. We also extend our gratitude to Intel for their assistance.
|
||||
|
||||
# Introduction to AMX Instruction Set
|
||||
|
||||
Intel Advanced Matrix Extensions (AMX) are a set of specialized instruction extensions introduced for the x86 architecture starting with Sapphire Rapids (4th generation Xeon Scalable processors) and onward. AMX accelerates large-scale matrix computations at the hardware level, particularly for the compute-intensive parts of deep learning inference and machine learning workloads. By introducing the concept of Tile registers, it loads 2D sub-matrices into dedicated Tile registers and performs matrix multiply-accumulate operations at the register level, significantly improving throughput and energy efficiency.
|
||||
|
||||
Each CPU core contains 8 dedicated registers (tmm0–tmm7), with each register capable of holding up to 16 rows × 64 bytes of data to store 2D sub-matrices. Additionally, there is a 64-byte configuration register (TILECFG) used to describe each tmm register's number of rows, columns, and row stride.
|
||||
|
||||
The main AMX instructions are summarized as follows:
|
||||
|
||||
| Instruction Category | Instruction Names | Description |
|
||||
|:---|:---|:---|
|
||||
| Configuration Instructions | LDTILECFG, STTILECFG, TILERELEASE, TILEZERO | Configure/reset Tile registers and metadata |
|
||||
| Load/Store Instructions | TILELOADD, TILELOADDT1, TILESTORED | Transfer data between memory and Tile registers |
|
||||
| INT8 Computation Instructions | TDPBSSD, TDPBUSD, TDPBUUD, TDPBSUD | Perform multiply and accumulate operations on int8 sub-matrices within Tiles |
|
||||
| BF16 Computation Instructions | TDPBF16PS | Perform multiply and accumulate operations on bfloat16 sub-matrices within Tiles |
|
||||
|
||||
To simplify development, Intel provides corresponding intrinsics, allowing C/C++ developers to leverage AMX's performance benefits without writing lengthy assembly code. For example:
|
||||
|
||||
```C++
|
||||
#include <immintrin.h>
|
||||
|
||||
_tile_loadconfig(cfg_ptr);
|
||||
_tile_loadd(tmm0, A_ptr, lda);
|
||||
_tile_loadd(tmm1, B_ptr, ldb);
|
||||
_tile_zero(tmm2)
|
||||
_tile_dpbf16ps(tmm2, tmm0, tmm1);
|
||||
_tile_stored(tmm2, C_ptr, ldc);
|
||||
_tile_release();
|
||||
```
|
||||
|
||||
The above code copies sub-matrices from memory (A_ptr, B_ptr) to Tile registers, calls the AMX BF16 compute instruction to multiply two sub-matrices, and then copies the result to memory (C_ptr).
|
||||
|
||||
Taking INT8 as an example, AMX can perform the multiplication of two 16×64 sub-matrices (32,768 multiply/add operations) with a single instruction in 16 CPU cycles, enabling each core to complete 2048 multiply/add operations per cycle — 8 times the performance of AVX-512. On an Intel Xeon 4 CPU, a single core can theoretically provide 4 TOPS of compute power, making it highly suitable for compute-intensive tasks on the CPU.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="amx_intro" src="../assets/amx_intro.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
|
||||
# AMX Kernel in KTransformers
|
||||
|
||||
Before version v0.3, KTransformers performed CPU matrix multiplications based on operators provided by llamafile. Unfortunately, llamafile's implementation had not yet been optimized for the AMX instruction set. This resulted in performance bottlenecks, even in strong hardware environments (such as Xeon 4th Gen + 4090), where inference speeds for large models like DeepSeek-V3 reached only 91 tokens/s during the prefill phase. The CPU thus remained a significant bottleneck. In long prompt scenarios, such performance is clearly unsatisfactory. To fully unleash CPU potential, we introduced a brand-new AMX optimization path along with multiple technical improvements in v0.3.
|
||||
|
||||
## 1. AMX Tiling-aware Memory Layout
|
||||
|
||||
AMX provides a high-throughput Tile register computation model, reducing instruction count and boosting theoretical throughput through coarse-grained matrix operations. However, to truly exploit AMX's potential, memory access efficiency is critical: because AMX transfers entire Tiles at once, misaligned Tiles and chaotic access patterns can cause severe cache misses, nullifying throughput gains.
|
||||
|
||||
Thus, in v0.3, we stopped directly memory-mapping GGUF-format files and introduced AMX Tiling-aware memory preprocessing during model loading. Specifically, expert weight matrices in MoE models are pre-rearranged into Tile-friendly sub-matrices whose shapes precisely match AMX Tile register dimensions, eliminating dynamic transposition overhead during inference. During rearrangement, we strictly align each sub-matrix's start address to 64 bytes to avoid cache line splits, and arrange sub-matrices sequentially according to computation access patterns, maximizing L1/L2 cache hit rates using compiler and hardware sequential prefetch capabilities.
|
||||
|
||||
For Int8 quantized formats, we adopted Symmetric Group-wise Quantization, with each column forming a group sharing a scale factor stored separately to maintain memory alignment for Tile data.
|
||||
|
||||
This AMX Tiling-aware memory layout design reduces memory latency while providing optimal input conditions for downstream computation kernels.
|
||||
|
||||
## 2. Cache-friendly AMX Kernel
|
||||
|
||||
During inference, we designed around the CPU’s multi-level cache hierarchy to perform computations in-place in high-speed caches, minimizing DRAM access frequency and overhead.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="amx" src="../assets/amx.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
As shown in the figure,
|
||||
- ① Expert weight matrices are first column-wise partitioned into multiple tasks dynamically scheduled across threads. Input activations are shared among tasks and typically reside in the shared L3 cache due to locality.
|
||||
- ② Within each task, expert weights are row-wise partitioned into blocks, with block sizes finely tuned to ensure input activations, weights, and intermediate results stay within L2 cache, avoiding DRAM access.
|
||||
- ③ ④ ⑤ Each block is treated as a set of sub-matrices matching AMX Tile registers, and during Tile-level computation, input Tiles (tmm0–tmm1) and expert Tiles (tmm2–tmm3) are loaded, and four AMX multiplication instructions directly generate and accumulate products into Tile registers (tmm4–tmm7), with output activations accumulated in Tile registers or L1 cache, avoiding additional data movement.
|
||||
|
||||
In short, we leveraged the cache hierarchy: every data element of expert weights and output activations accesses DRAM only once, with the other accesses hitting L2 or higher caches; input activations are accessed from DRAM only once and later hit in L3 or higher caches. This significantly reduces main memory traffic and improves overall execution efficiency.
|
||||
|
||||
## 3. AVX-512 Kernel Adaptation for Low Arithmetic Intensity Scenarios
|
||||
|
||||
Although AMX is highly efficient for large-scale matrix multiplication, it performs poorly under low arithmetic intensity, such as vector-matrix operations in the decode phase. This is because dispatching AMX Tiles involves fixed instruction overhead, which becomes wasteful when the data volume is insufficient to fill a Tile, causing reduced throughput.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="amx_avx" src="../assets/amx_avx.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
To address this, we introduced a lightweight AVX-512 kernel as a complement. This kernel follows the same memory layout as the AMX kernel but replaces heavy AMX matrix-matrix multiplications with fine-grained AVX-512 vector-matrix multiplications, lowering latency for small matrices.
|
||||
|
||||
KTransformers dynamically selects between AMX and AVX-512 kernels at runtime based on arithmetic intensity: AMX kernels are automatically selected during long prompt prefill phases (where each expert handles more than 4 tokens on average), while short prompt prefill and decode phases dynamically switch to AVX-512 kernels. This ensures optimal efficiency under different arithmetic intensity conditions.
|
||||
|
||||
## 4. MoE Operator Fusion and Dynamic Scheduling
|
||||
|
||||
MoE models have many experts per layer, each requiring three matrix multiplications (Gate, Up, Down projections), leading to many small matrix multiplication tasks. Independently scheduling each small task would cause massive synchronization overhead between threads, dragging down overall inference speed.
|
||||
|
||||
Thus, we fused the same type of matrix computations for all experts in a layer into large unified tasks. Furthermore, as there are no data dependencies between Gate and Up projections, their computations can also be fused, ultimately consolidating a layer’s matrix multiplications into two major tasks, greatly reducing scheduling overhead.
|
||||
|
||||
To address load imbalance — especially during the prefill phase where expert activations can be highly skewed — we introduced a dynamic task scheduling strategy. Each matrix multiplication task is further split into multiple fine-grained sub-tasks, evenly distributed among CPU threads initially. Once a thread completes its assigned tasks, it atomically "steals" tasks from others, greatly mitigating load imbalance and achieving near-optimal CPU resource utilization.
|
||||
|
||||
Thanks to these optimizations, our kernel can achieve 21 TFLOPS of BF16 throughput and 35 TOPS of Int8 throughput on Xeon4 CPUs — about 4× faster than PyTorch’s general AMX kernel. For DeepSeek-V3, pairing a Xeon4 CPU with a single RTX 4090 GPU achieves 418 tokens/s end-to-end throughput, close to the performance of multi-machine, multi-GPU setups. KTransformers’ AMX kernel is the first AMX kernel specifically designed for MoE inference scenarios, significantly lowering the hardware barrier for large model deployment and enabling more developers to enjoy GPU cluster level inference experiences at lower cost.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="onednn_1" src="../assets/onednn_1.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
# Usage
|
||||
|
||||
## Checking AMX Support
|
||||
|
||||
Before enabling the AMX-optimized kernels, it is important to verify whether your CPU supports the AMX instruction set. You can check AMX availability with the following command:
|
||||
|
||||
```bash
|
||||
lscpu | grep -i amx
|
||||
```
|
||||
|
||||
If your system supports AMX, you should see output similar to:
|
||||
|
||||
```bash
|
||||
Flags: ... amx-bf16 amx-int8 amx-tile ...
|
||||
```
|
||||
|
||||
If no amx-related flags are found, your CPU may not support AMX, or AMX may be disabled in BIOS settings. In that case, please ensure that:
|
||||
- You are using a Sapphire Rapids (Xeon 4th Gen) or newer CPU.
|
||||
- AMX support is enabled in your system BIOS under CPU feature settings.
|
||||
|
||||
## Enabling AMX in KTransformers
|
||||
|
||||
KTransformers allows users to easily switch between different backends through simple YAML configuration modifications. To enable AMX, modify the injection configuration of your experts by specifying backend as AMXInt8 or AMXBF16:
|
||||
|
||||
```YAML
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert parallelism
|
||||
kwargs:
|
||||
prefill_device: "cuda"
|
||||
prefill_op: "KExpertsTorch"
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda"
|
||||
backend: "AMXInt8" # or "AMXBF16" or "llamafile" (default)
|
||||
```
|
||||
|
||||
**Note:** Currently, using AMXInt8 requires reading weights from a BF16 GGUF file and performing online quantization during model loading. This may cause slightly slower load times. Future versions will provide pre-quantized weights to eliminate this overhead.
|
||||
|
||||

|
||||
|
|
@ -1,326 +0,0 @@
|
|||
<!-- omit in toc -->
|
||||
|
||||
# GPT-4/o1-level Local VSCode Copilot on a Desktop with only 24GB VRAM
|
||||
|
||||
- [SUMMARY](#summary)
|
||||
- [Show Case Environment](#show-case-environment)
|
||||
- [Bench Result](#bench-result)
|
||||
- [V0.2.1](#v021)
|
||||
- [Memory consumption:](#memory-consumption)
|
||||
- [Change Log](#change-log)
|
||||
- [Benchmark Results](#benchmark-results)
|
||||
- [V0.2](#v02)
|
||||
- [Settings](#settings)
|
||||
- [Memory consumption:](#memory-consumption-1)
|
||||
- [Benchmark Results](#benchmark-results-1)
|
||||
- [V0.3-Preview](#v03-preview)
|
||||
- [Settings](#settings-1)
|
||||
- [Memory consumptions:](#memory-consumptions)
|
||||
- [Benchmark results](#benchmark-results-2)
|
||||
- [How to Run](#how-to-run)
|
||||
- [v0.2.2 \& v0.2.3 longer context \& FP8 kernel](#v022--v023-longer-context--fp8-kernel)
|
||||
- [longer context](#longer-context)
|
||||
- [FP8 kernel](#fp8-kernel)
|
||||
- [V0.2 \& V0.2.1 Showcase](#v02--v021-showcase)
|
||||
- [Single socket version (32 cores)](#single-socket-version-32-cores)
|
||||
- [Dual socket version (64 cores)](#dual-socket-version-64-cores)
|
||||
- [V0.3 Showcase](#v03-showcase)
|
||||
- [Dual socket version (64 cores)](#dual-socket-version-64-cores-1)
|
||||
- [Some Explanations](#some-explanations)
|
||||
- [Next](#next)
|
||||
- [Faster](#faster)
|
||||
- [Easier](#easier)
|
||||
- [FAQ](#faq)
|
||||
- [R1 No Thinking](#r1-no-thinking)
|
||||
- [More FAQ](#more-faq)
|
||||
|
||||
# SUMMARY
|
||||
|
||||
> **Feb 10, 2025**: Support DeepseekR1 and V3 on single (24GB VRAM)/multi gpu and 382G DRAM, up to 3~28x speedup.<br>
|
||||
|
||||
Hi, we're the KTransformers team (formerly known for our local CPU/GPU hybrid inference open source project with DeepSeek-V2).
|
||||
|
||||
We've heard your requests for DeepSeek-R1/V3 support—and we're excited to finally deliver!
|
||||
Apologies for the wait, but we've been cooking up something truly amazing!
|
||||
|
||||
Today, we're proud to announce that we not only support DeepSeek-R1/V3, as showcased in the video below:
|
||||
|
||||
https://github.com/user-attachments/assets/ebd70bfa-b2c1-4abb-ae3b-296ed38aa285
|
||||
|
||||
</p>
|
||||
|
||||
- **[NEW!!!] Local 671B DeepSeek-Coder-V3/R1:** Running its Q4_K_M version using only 14GB VRAM and 382GB DRAM.
|
||||
- Prefill Speed (tokens/s):
|
||||
- KTransformers: 54.21 (32 cores) → 74.362 (dual-socket, 2×32 cores) → 255.26 (optimized AMX-based MoE kernel, V0.3 only) → 286.55 (selectively using 6 experts, V0.3 only)
|
||||
- Compared to 10.31 tokens/s in llama.cpp with 2×32 cores, achieving up to **27.79× speedup**.
|
||||
- Decode Speed (tokens/s):
|
||||
- KTransformers: 8.73 (32 cores) → 11.26 (dual-socket, 2×32 cores) → 13.69 (selectively using 6 experts, V0.3 only)
|
||||
- Compared to 4.51 tokens/s in llama.cpp with 2×32 cores, achieving up to **3.03× speedup**.
|
||||
|
||||
We also give our upcoming optimizations previews, including an Intel AMX-accelerated kernel and a selective expert activation method, which will significantly enhance performance. With V0.3-preview, we achieve up to 286 tokens/s for prefill, making it up to **28× faster than llama.cpp** for local inference.
|
||||
The binary distribution is available now and the source code will come ASAP! Check out the wheel package [here](https://github.com/kvcache-ai/ktransformers/releases/download/v0.1.4/ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl)
|
||||
|
||||
> **Feb 15, 2025**: KTransformers V0.2.1: Longer Context (from 4K to 8K for 24GB VRAM) & Slightly Faster Speed (+15%) (Up to 16 Tokens/s), update docs [here](./doc/en/DeepseekR1_V3_tutorial.md) and [online books](https://kvcache-ai.github.io/ktransformers/).
|
||||
|
||||
We speed up the decode and prefill speed a littlt bit. The reason for the limited performance improvement mainly lies in the fact that the inference process is still constrained by the CPU's computational speed and memory bandwidth. The MLA part handled by the GPU accounts for a relatively small proportion.
|
||||
|
||||
Besides the improvements in speed, we've also significantly updated the documentation to enhance usability, including:<br>
|
||||
|
||||
- Added Multi-GPU configuration tutorial.
|
||||
- Consolidated installation guide.
|
||||
- Add a detailed tutorial on registering extra GPU memory with ExpertMarlin;
|
||||
|
||||
## Show Case Environment
|
||||
|
||||
We run our best performance tests (V0.2) on <br>
|
||||
CPU: Intel (R) Xeon (R) Gold 6454S 1T DRAM (2 NUMA nodes) <br>
|
||||
GPU: 4090D 24G VRAM <br>
|
||||
Memory: standard DDR5-4800 server DRAM (1 TB), each socket with 8×DDR5-4800
|
||||
|
||||
## Bench Result
|
||||
|
||||
### V0.2.1
|
||||
|
||||
- Model: DeepseekV3-q4km (int4)<br>
|
||||
- CPU: cpu_model_name: Intel (R) Xeon (R) Gold 6454S, 32 cores per socket, 2 sockets, 2 numa nodes
|
||||
- GPU: 4090 24G VRAM
|
||||
- We test after enough warm up
|
||||
|
||||
#### Memory consumption:
|
||||
|
||||
- Single socket: 382G DRAM, at least 14GB VRAM
|
||||
- Dual socket: 1T DRAM, at least 14GB VRAM
|
||||
|
||||
#### Change Log
|
||||
|
||||
- Longer Context (from 4K to 8K for 24GB VRAM) and Slightly Faster Speed (+15%):<br>
|
||||
Integrated the highly efficient Triton MLA Kernel from the fantastic sglang project, enable much longer context length and slightly faster prefill/decode speed
|
||||
- We suspect that some of the improvements come from the change of hardware platform (4090D->4090)
|
||||
|
||||
#### Benchmark Results
|
||||
|
||||
"6 experts" case is part of V0.3's preview
|
||||
|
||||
|
||||
| Prompt | hi (2) | 1K (969) | 2K (1930) | 4K (3846) | 8K (7678) |
|
||||
| -------------------- | -------- | --------- | --------- | ----------------------- | --------- |
|
||||
| Output length | 10tokens | 300tokens | 300tokens | 300tokens | 300tokens |
|
||||
| **6 experts V0.2.0** | | | | | |
|
||||
| Prefill token/s | 13 | 105 | 102 | 88 | CUDA OOM |
|
||||
| decode token/s | 16.8 | 15.4 | 14.2 | 13.0 | CUDA OOM |
|
||||
| **6 experts V0.2.1** | | | | | |
|
||||
| Prefill token/s | 13 | 111 | 112.5 | 102**(1.16x speedup)** | 101 |
|
||||
| decode token/s | 16.8 | 15.9 | 15.4 | 14.9**(1.15x speedup)** | 13.9 |
|
||||
| **8 experts V0.2.1** | | | | | |
|
||||
| Prefill token/s | 12.2 | 88.2 | 88.5 | 81.9 | 80 |
|
||||
| Decode token/s | 13.4 | 13.5 | 13.4 | 13.2 | 12.4 |
|
||||
|
||||
### V0.2
|
||||
|
||||
#### Settings
|
||||
|
||||
- Model: DeepseekV3-q4km (int4)<br>
|
||||
- CPU: cpu_model_name: Intel (R) Xeon (R) Gold 6454S, 32 cores per socket, 2 sockets, 2 numa nodes
|
||||
- GPU: 4090D 24G VRAM
|
||||
- We test after enough warm up
|
||||
|
||||
#### Memory consumption:
|
||||
|
||||
- Single socket: 382G DRAM, at least 14GB VRAM
|
||||
- Dual socket: 1T DRAM, at least 14GB VRAM
|
||||
|
||||
#### Benchmark Results
|
||||
|
||||
"6 experts" case is part of V0.3's preview
|
||||
|
||||
|
||||
| Prompt<br>(500 tokens) | Dual socket Ktrans (6 experts) | Dual socket Ktrans (8 experts) | Single socket Ktrans (6 experts) | Single socket Ktrans (8 experts) | llama.cpp (8 experts) |
|
||||
| ---------------------- | ------------------------------ | ------------------------------ | -------------------------------- | -------------------------------- | --------------------- |
|
||||
| Prefill token/s | 97.32 | 82.94 | 65.14 | 54.21 | 10.31 |
|
||||
| Decode token/s | 13.69 | 12.208 | 10.303 | 8.73 | 4.51 |
|
||||
|
||||
**The highest speedup reaches up to <u>3.03x</u> in decoding and <u>9.44x</u> in prefill.**
|
||||
|
||||
### V0.3-Preview
|
||||
|
||||
#### Settings
|
||||
|
||||
- Model: DeepseekV3-BF16 (online quant into int8 for CPU and int4 for GPU)
|
||||
- CPU: cpu_model_name: Intel (R) Xeon (R) Gold 6454S, 32 cores per socket, 2 socket, 2 numa nodes
|
||||
- GPU: (1~4)x 4090D 24GVRAM (requires more VRAM for longer prompt)
|
||||
|
||||
#### Memory consumptions:
|
||||
|
||||
- 644GB DRAM, at least 14GB VRAM
|
||||
|
||||
#### Benchmark results
|
||||
|
||||
|
||||
| Prompt length | 1K | 2K | 4K | 8K |
|
||||
| ---------------------------------- | ------ | ------ | ------ | ------ |
|
||||
| KTrans (8 experts) Prefill token/s | 185.96 | 255.26 | 252.58 | 195.62 |
|
||||
| KTrans (6 experts) Prefill token/s | 203.70 | 286.55 | 271.08 | 207.20 |
|
||||
|
||||
**The prefill of KTrans V0.3 is up to <u>3.45x</u> times faster than KTrans V0.2, and is up to <u>27.79x</u> times faster than llama.cpp.**
|
||||
**The decoding speed is the same as KTrans V0.2 (6 experts version) so it is omitted**
|
||||
|
||||
The main acceleration comes from
|
||||
|
||||
- Intel AMX instruction set and our specially designed cache friendly memory layout
|
||||
- Expert selection strategy that selects fewer experts based on offline profile results of out of domain data
|
||||
|
||||
*From our research on DeepSeekV2, DeepSeekV3 and DeepSeekR1,
|
||||
when we slightly decrease the activation experts num in inference,
|
||||
the output quality doesn't change. But the speed of decoding and prefill
|
||||
is speed up which is inspiring. So our showcase makes use of this finding*
|
||||
|
||||
## How to Run
|
||||
|
||||
### v0.2.4
|
||||
We provide a server script, which supports multi-concurrency functionality in version v0.2.4.
|
||||
|
||||
```
|
||||
python ktransformers/server/main.py --model_path /mnt/data/models/DeepSeek-V3 --gguf_path /mnt/data/models/DeepSeek-V3-GGUF/DeepSeek-V3-Q4_K_M/ --cpu_infer 62 --optimize_config_path ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-serve.yaml --port 10002 --chunk_size 256 --max_new_tokens 1024 --max_batch_size 4 --port 10002 --cache_lens 32768 --backend_type balance_serve
|
||||
```
|
||||
It features the following arguments:
|
||||
|
||||
- `--chunk_size`: Maximum number of tokens processed in a single run by the engine.
|
||||
- `--cache_lens`: Total length of kvcache allocated by the scheduler. All requests share a kvcache space corresponding to 32768 tokens, and the space occupied will be released after the requests are completed.
|
||||
- `--backend_type`: `balance_serve` is a multi-concurrency backend engine introduced in version v0.2.4. The original single-concurrency engine is `ktransformers`.
|
||||
- `--max_batch_size`: Maximum number of requests (prefill + decode) processed in a single run by the engine. (Supported only by `balance_serve`)
|
||||
|
||||
### v0.2.2 & v0.2.3 longer context & FP8 kernel
|
||||
|
||||
#### longer context
|
||||
|
||||
To use this feature, [install flashinfer](https://github.com/flashinfer-ai/flashinfer) first.
|
||||
|
||||
Note: The latest MLA kernel in FlashInfer still has a few minor issues. They are continuously fixing them on the main branch. If you are using FlashInfer, please install it from the main source code.
|
||||
|
||||
If you want to use long context(longer than 20K) for prefill, enable the matrix absorption MLA during the prefill phase, which will significantly reduce the size of the kv cache. Modify yaml file like this:
|
||||
|
||||
```
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.self_attn$"
|
||||
replace:
|
||||
class: ktransformers.operators.attention.KDeepseekV2Attention # optimized MLA implementation
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
prefill_device: "cuda"
|
||||
absorb_for_prefill: True # change this to True to enable long context(prefill may slower).
|
||||
```
|
||||
|
||||
If the VRAM is still insufficient, try reducing the `chunk_size` parameter (default is 8192) to further decrease the intermediate results during chunk prefill.
|
||||
|
||||
#### FP8 kernel
|
||||
|
||||
The DeepSeek-AI team provides FP8 safetensors for DeepSeek-R1/V3 models. We achieve performance optimization through the following works:
|
||||
|
||||
- **FP8 GPU Kernel Integration**: FP8 linear layer acceleration kernels integrated in KTransformers
|
||||
- **Hybrid Quantization Architecture**:
|
||||
- Attention and Shared-Expert modules use FP8 precision (enhances computational accuracy)
|
||||
- Experts modules retain GGML quantization (GGUF format, reside in CPU to save GPU memory)
|
||||
|
||||
So those who are persuing the best performance can use the FP8 linear kernel for DeepSeek-V3/R1.
|
||||
|
||||
The detailed guide is [here](./fp8_kernel.md).
|
||||
|
||||
### V0.2 & V0.2.1 Showcase
|
||||
|
||||
#### Single socket version (32 cores)
|
||||
|
||||
Our local_chat test command is:
|
||||
|
||||
```shell
|
||||
numactl -N 1 -m 1 python ./ktransformers/local_chat.py --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 33 --max_new_tokens 1000
|
||||
<when you see chat, then press enter to load the text prompt_file>
|
||||
```
|
||||
|
||||
`<your model path>` can be local or set from online huggingface like deepseek-ai/DeepSeek-V3. If online encounters connection problem, try use mirror (hf-mirror.com) <br>
|
||||
`<your gguf path>` can also be online, but as its large we recommend you download it and quantize the model to what you want (notice it's the dir path) <br>
|
||||
`--max_new_tokens 1000` is the max output token length. If you find the answer is truncated, you
|
||||
can increase the number for longer answer (But be aware of OOM, and increase it will slow down the generation rate.).
|
||||
|
||||
The command `numactl -N 1 -m 1` aims to advoid data transfer between numa nodes<br>
|
||||
Attention! If you are testing R1 and it may skip thinking. So you can add arg: `--force_think true`. This is explained in [FAQ](#faq) part
|
||||
|
||||
#### Dual socket version (64 cores)
|
||||
|
||||
Make sure before you install (use install.sh or `make dev_install`), setting the env var `USE_NUMA=1` by `export USE_NUMA=1` (if already installed, reinstall it with this env var set). You may check the doc [here](./install.md) for install details. <br>
|
||||
|
||||
Test Command:
|
||||
|
||||
```shell
|
||||
# ---For those who have not installed ktransformers---
|
||||
# git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
# cd ktransformers
|
||||
# git submodule init
|
||||
# git submodule update
|
||||
# export USE_NUMA=1
|
||||
# make dev_install # or sh ./install.sh
|
||||
# ----------------------------------------------------
|
||||
python ./ktransformers/local_chat.py --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 65 --max_new_tokens 1000
|
||||
<when you see chat, then press enter to load the text prompt_file>
|
||||
```
|
||||
|
||||
The parameters' meaning is the same. But As we use dual socket, we set cpu_infer to 65
|
||||
|
||||
### V0.3 Showcase
|
||||
|
||||
#### Dual socket version (64 cores)
|
||||
|
||||
Our local_chat test command is:
|
||||
|
||||
```shell
|
||||
wget https://github.com/kvcache-ai/ktransformers/releases/download/v0.1.4/ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl
|
||||
pip install ./ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl
|
||||
python -m ktransformers.local_chat --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 65 --max_new_tokens 1000
|
||||
<when you see chat, then press enter to load the text prompt_file>
|
||||
```
|
||||
|
||||
The parameters' meaning is the same with V0.2. But As we use dual socket, we set cpu_infer to 65
|
||||
|
||||
## Some Explanations
|
||||
|
||||
1. Also we want to make further use of our two NUMA nodes on Xeon Gold cpu.
|
||||
To avoid the cost of data transfer between nodes, we "copy" the critical matrix on
|
||||
both nodes which takes more memory consumption but accelerates the prefill and decoding process.
|
||||
But this method takes huge memory and slow when loading weights, So be patient when loading
|
||||
and monitor the memory usage. We are going to optimize this huge memory overhead. Stay tuned~ <br>
|
||||
2. The command args `--cpu_infer 65` specifies how many cores to use (it's ok that it exceeds the physical number,
|
||||
but it's not the more the better. Adjust it slightly lower to your actual number of cores)<br>
|
||||
3. Why CPU/GPU Hybrid Inference?
|
||||
DeepSeek's MLA operators are highly computationally intensive. While running everything on CPU is possible, offloading the heavy computations to the GPU results in a massive performance boost.
|
||||
4. Where Does the Speedup Come From?
|
||||
|
||||
- Expert Offload: Unlike traditional layer-based or KVCache offloading (as seen in llama.cpp), we offload the expert computation to the CPU and MLA/KVCache to GPU, aligning perfectly with DeepSeek’s architecture for optimal efficiency.
|
||||
- Intel AMX Optimization – Our AMX-accelerated kernel is meticulously tuned, running several times faster than existing llama.cpp implementations. We plan to open-source this kernel after cleansing and are considering upstream contributions to llama.cpp.
|
||||
5. Why Intel CPUs?
|
||||
Intel is currently the only CPU vendor that supports AMX-like instructions, which delivers significantly better performance compared to AVX-only alternatives.
|
||||
|
||||
## Next
|
||||
|
||||
### Faster
|
||||
|
||||
* The FlashInfer (https://github.com/flashinfer-ai/flashinfer) project is releasing an even more efficient fused MLA operator, promising further speedups
|
||||
* vLLM has explored multi-token prediction in DeepSeek-V3, and support is on our roadmap for even better performance
|
||||
* We are collaborating with Intel to enhance the AMX kernel (v0.3) and optimize for Xeon6/MRDIMM
|
||||
|
||||
### Easier
|
||||
|
||||
* Official Docker images to simplify installation
|
||||
* Fix the server integration for web API access
|
||||
* Fix the local chat only accepting a single line prompt (currently \n begins generating prompt)
|
||||
* Support for more quantization types, including the highly requested dynamic quantization from unsloth
|
||||
|
||||
Stay tuned for more updates!
|
||||
|
||||
## FAQ
|
||||
|
||||
### R1 No Thinking
|
||||
|
||||
Attention! If you are testing R1 and it may skip thinking. So you can add arg: `--force_think true`. The detail is in [FAQ](./FAQ.md) part <br>
|
||||
|
||||
### More FAQ
|
||||
|
||||
[See detail](./FAQ.md)
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
# Docker
|
||||
|
||||
## Prerequisites
|
||||
* Docker must be installed and running on your system.
|
||||
* Create a folder to store big models & intermediate files (ex. /mnt/models)
|
||||
|
||||
## Images
|
||||
There is a Docker image available for our project, you can pull the docker image by:
|
||||
```
|
||||
docker pull approachingai/ktransformers:0.2.1
|
||||
```
|
||||
**Notice**: In this image, we compile the ktransformers in AVX512 instuction CPUs, if your cpu not support AVX512, it is suggested to recompile and install ktransformers in the /workspace/ktransformers directory within the container.
|
||||
|
||||
## Building docker image locally
|
||||
- Download Dockerfile in [there](../../Dockerfile)
|
||||
|
||||
- finish, execute
|
||||
```bash
|
||||
docker build -t approachingai/ktransformers:0.2.1 .
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Assuming you have the [nvidia-container-toolkit](https://github.com/NVIDIA/nvidia-container-toolkit) that you can use the GPU in a Docker container.
|
||||
```
|
||||
docker run --gpus all -v /path/to/models:/models --name ktransformers -itd approachingai/ktransformers:0.2.1
|
||||
docker exec -it ktransformers /bin/bash
|
||||
python -m ktransformers.local_chat --gguf_path /models/path/to/gguf_path --model_path /models/path/to/model_path --cpu_infer 33
|
||||
```
|
||||
|
||||
More operators you can see in the [readme](../../README.md)
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
# Intel GPU Docker Guide (Beta)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* Docker must be installed and running on your system.
|
||||
* Create a folder to store big models & intermediate files (e.g., /mnt/models)
|
||||
* **Before proceeding, ensure the Intel GPU driver is installed correctly on your host:** [Installation Guide](./xpu.md#1-install-intel-gpu-driver)
|
||||
|
||||
---
|
||||
|
||||
## Building the Docker Image Locally
|
||||
|
||||
1. Clone the repository and navigate to the project directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
```
|
||||
|
||||
2. Build the Docker image using the XPU-specific [Dockerfile.xpu](../../Dockerfile.xpu):
|
||||
|
||||
```bash
|
||||
sudo http_proxy=$HTTP_PROXY \
|
||||
https_proxy=$HTTPS_PROXY \
|
||||
docker build \
|
||||
--build-arg http_proxy=$HTTP_PROXY \
|
||||
--build-arg https_proxy=$HTTPS_PROXY \
|
||||
-t kt_xpu:0.3.1 \
|
||||
-f Dockerfile.xpu \
|
||||
.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running the Container
|
||||
|
||||
### 1. Start the container
|
||||
|
||||
```bash
|
||||
sudo docker run -td --privileged \
|
||||
--net=host \
|
||||
--device=/dev/dri \
|
||||
--shm-size="16g" \
|
||||
-v /path/to/models:/models \
|
||||
-e http_proxy=$HTTP_PROXY \
|
||||
-e https_proxy=$HTTPS_PROXY \
|
||||
--name ktransformers_xpu \
|
||||
kt_xpu:0.3.1
|
||||
```
|
||||
|
||||
**Note**: Replace `/path/to/models` with your actual model directory path (e.g., `/mnt/models`).
|
||||
|
||||
---
|
||||
|
||||
### 2. Access the container
|
||||
|
||||
```bash
|
||||
sudo docker exec -it ktransformers_xpu /bin/bash
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Set required XPU environment variables (inside the container)
|
||||
|
||||
```bash
|
||||
export SYCL_CACHE_PERSISTENT=1
|
||||
export ONEAPI_DEVICE_SELECTOR=level_zero:0
|
||||
export SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Run the sample script
|
||||
|
||||
```bash
|
||||
python ktransformers/local_chat.py \
|
||||
--model_path deepseek-ai/DeepSeek-R1 \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/xpu/DeepSeek-V3-Chat.yaml \
|
||||
--cpu_infer <cpu_cores + 1> \
|
||||
--device xpu \
|
||||
--max_new_tokens 200
|
||||
```
|
||||
|
||||
**Note**:
|
||||
|
||||
* Replace `<path_to_gguf_files>` with the path to your GGUF model files.
|
||||
* Replace `<cpu_cores + 1>` with the number of CPU cores you want to use plus one.
|
||||
|
||||
---
|
||||
|
||||
## Additional Information
|
||||
|
||||
For more configuration options and usage details, refer to the [project README](../../README.md). To run KTransformers natively on XPU (outside of Docker), please refer to [xpu.md](./xpu.md).
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
<!-- omit in toc -->
|
||||
# FAQ
|
||||
- [Install](#install)
|
||||
- [Q: ImportError: /lib/x86\_64-linux-gnu/libstdc++.so.6: version GLIBCXX\_3.4.32' not found](#q-importerror-libx86_64-linux-gnulibstdcso6-version-glibcxx_3432-not-found)
|
||||
- [Q: DeepSeek-R1 not outputting initial token](#q-deepseek-r1-not-outputting-initial--token)
|
||||
- [Usage](#usage)
|
||||
- [Q: If I got more VRAM than the model's requirement, how can I fully utilize it?](#q-if-i-got-more-vram-than-the-models-requirement-how-can-i-fully-utilize-it)
|
||||
- [Q: If I don't have enough VRAM, but I have multiple GPUs, how can I utilize them?](#q-if-i-dont-have-enough-vram-but-i-have-multiple-gpus-how-can-i-utilize-them)
|
||||
- [Q: How to get the best performance?](#q-how-to-get-the-best-performance)
|
||||
- [Q: My DeepSeek-R1 model is not thinking.](#q-my-deepseek-r1-model-is-not-thinking)
|
||||
- [Q: Loading gguf error](#q-loading-gguf-error)
|
||||
- [Q: Version \`GLIBCXX\_3.4.30' not found](#q-version-glibcxx_3430-not-found)
|
||||
- [Q: When running the bfloat16 moe model, the data shows NaN](#q-when-running-the-bfloat16-moe-model-the-data-shows-nan)
|
||||
- [Q: Using fp8 prefill very slow.](#q-using-fp8-prefill-very-slow)
|
||||
- [Q: Possible ways to run graphics cards using volta and turing architectures](#q-possible-ways-to-run-graphics-cards-using-volta-and-turing-architectures)
|
||||
## Install
|
||||
### Q: ImportError: /lib/x86_64-linux-gnu/libstdc++.so.6: version GLIBCXX_3.4.32' not found
|
||||
```
|
||||
in Ubuntu 22.04 installation need to add the:
|
||||
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update
|
||||
sudo apt-get install --only-upgrade libstdc++6
|
||||
```
|
||||
from-https://github.com/kvcache-ai/ktransformers/issues/117#issuecomment-2647542979
|
||||
### Q: DeepSeek-R1 not outputting initial <think> token
|
||||
|
||||
> from deepseek-R1 doc:<br>
|
||||
> Additionally, we have observed that the DeepSeek-R1 series models tend to bypass thinking pattern (i.e., outputting "\<think>\n\n\</think>") when responding to certain queries, which can adversely affect the model's performance. To ensure that the model engages in thorough reasoning, we recommend enforcing the model to initiate its response with "\<think>\n" at the beginning of every output.
|
||||
|
||||
So we fix this by manually adding "\<think>\n" token at prompt end (you can check out at local_chat.py),
|
||||
and pass the arg `--force_think true ` can let the local_chat initiate the response with "\<think>\n"
|
||||
|
||||
from-https://github.com/kvcache-ai/ktransformers/issues/129#issue-2842799552
|
||||
|
||||
## Usage
|
||||
### Q: If I got more VRAM than the model's requirement, how can I fully utilize it?
|
||||
|
||||
1. Get larger context.
|
||||
1. local_chat.py: You can increase the context window size by setting `--max_new_tokens` to a larger value.
|
||||
2. server: Increase the `--cache_lens' to a larger value.
|
||||
2. Move more weights to the GPU.
|
||||
Refer to the ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu-4.yaml
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\.([4-10])\\.mlp\\.experts$" # inject experts in layer 4~10 as marlin expert
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts
|
||||
kwargs:
|
||||
generate_device: "cuda:0" # run in cuda:0; marlin only support GPU
|
||||
generate_op: "KExpertsMarlin" # use marlin expert
|
||||
recursive: False
|
||||
```
|
||||
You can modify layer as you want, eg. `name: "^model\\.layers\\.([4-10])\\.mlp\\.experts$"` to `name: "^model\\.layers\\.([4-12])\\.mlp\\.experts$"` to move more weights to the GPU.
|
||||
|
||||
> Note: The first matched rule in yaml will be applied. For example, if you have two rules that match the same layer, only the first rule's replacement will be valid.
|
||||
> Note:Currently, executing experts on the GPU will conflict with CUDA Graph. Without CUDA Graph, there will be a significant slowdown. Therefore, unless you have a substantial amount of VRAM (placing a single layer of experts for DeepSeek-V3/R1 on the GPU requires at least 5.6GB of VRAM), we do not recommend enabling this feature. We are actively working on optimization.
|
||||
> Note KExpertsTorch is untested.
|
||||
|
||||
|
||||
### Q: If I don't have enough VRAM, but I have multiple GPUs, how can I utilize them?
|
||||
|
||||
Use the `--optimize_config_path ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu.yaml` to load the two optimized rule yaml file. You may also use it as an example to write your own 4/8 gpu optimized rule yaml file.
|
||||
|
||||
> Note: The ktransformers' multi-gpu stratigy is pipline, which is not able to speed up the model's inference. It's only for the model's weight distribution.
|
||||
|
||||
### Q: How to get the best performance?
|
||||
|
||||
You have to set `--cpu_infer` to the number of cores you want to use. The more cores you use, the faster the model will run. But it's not the more the better. Adjust it slightly lower to your actual number of cores.
|
||||
|
||||
### Q: My DeepSeek-R1 model is not thinking.
|
||||
|
||||
According to DeepSeek, you need to enforce the model to initiate its response with "\<think>\n" at the beginning of every output by passing the arg `--force_think True `.
|
||||
|
||||
### Q: Loading gguf error
|
||||
|
||||
Make sure you:
|
||||
1. Have the `gguf` file in the `--gguf_path` directory.
|
||||
2. The directory only contains gguf files from one model. If you have multiple models, you need to separate them into different directories.
|
||||
3. The folder name it self should not end with `.gguf`, eg. `Deep-gguf` is correct, `Deep.gguf` is wrong.
|
||||
4. The file itself is not corrupted; you can verify this by checking that the sha256sum matches the one from huggingface, modelscope, or hf-mirror.
|
||||
|
||||
### Q: Version `GLIBCXX_3.4.30' not found
|
||||
The detailed error:
|
||||
>ImportError: /mnt/data/miniconda3/envs/xxx/bin/../lib/libstdc++.so.6: version `GLIBCXX_3.4.30' not found (required by /home/xxx/xxx/ktransformers/./cpuinfer_ext.cpython-312-x86_64-linux-gnu.so)
|
||||
|
||||
Running `conda install -c conda-forge libstdcxx-ng` can solve the problem.
|
||||
|
||||
|
||||
### Q: When running the bfloat16 moe model, the data shows NaN
|
||||
The detailed error:
|
||||
```shell
|
||||
Traceback (most recent call last):
|
||||
File "/root/ktransformers/ktransformers/local_chat.py", line 183, in <module>
|
||||
fire.Fire(local_chat)
|
||||
File "/usr/local/lib/python3.10/dist-packages/fire/core.py", line 135, in Fire
|
||||
component_trace = _Fire(component, args, parsed_flag_args, context, name)
|
||||
File "/usr/local/lib/python3.10/dist-packages/fire/core.py", line 468, in _Fire
|
||||
component, remaining_args = _CallAndUpdateTrace(
|
||||
File "/usr/local/lib/python3.10/dist-packages/fire/core.py", line 684, in _CallAndUpdateTrace
|
||||
component = fn(*varargs, **kwargs)
|
||||
File "/root/ktransformers/ktransformers/local_chat.py", line 177, in local_chat
|
||||
generated = prefill_and_generate(
|
||||
File "/root/ktransformers/ktransformers/util/utils.py", line 204, in prefill_and_generate
|
||||
next_token = decode_one_tokens(cuda_graph_runner, next_token.unsqueeze(0), position_ids, cache_position, past_key_values, use_cuda_graph).to(torch_device)
|
||||
File "/root/ktransformers/ktransformers/util/utils.py", line 128, in decode_one_tokens
|
||||
next_token = torch.multinomial(probs, num_samples=1).squeeze(1)
|
||||
RuntimeError: probability tensor contains either `inf`, `nan` or element < 0
|
||||
```
|
||||
**SOLUTION**: The issue of running ktransformers on Ubuntu 22.04 is caused by the current system's g++ version being too old, and the pre-defined macros do not include avx_bf16. We have tested and confirmed that it works on g++ 11.4 in Ubuntu 22.04.
|
||||
|
||||
### Q: Using fp8 prefill very slow.
|
||||
|
||||
The FP8 kernel is build by JIT, so the first run will be slow. The subsequent runs will be faster.
|
||||
|
||||
### Q: Possible ways to run graphics cards using volta and turing architectures
|
||||
|
||||
From: https://github.com/kvcache-ai/ktransformers/issues/374
|
||||
|
||||
1. First, download the latest source code using git.
|
||||
2. Then, modify the DeepSeek-V3-Chat-multi-gpu-4.yaml in the source code and all related yaml files, replacing all instances of KLinearMarlin with KLinearTorch.
|
||||
3. Next, you need to compile from the ktransformers source code until it successfully compiles on your local machine.
|
||||
4. Then, install flash-attn. It won't be used, but not installing it will cause an error.
|
||||
5. Then, modify local_chat.py, replacing all instances of flash_attention_2 with eager.
|
||||
6. Then, run local_chat.py. Be sure to follow the official tutorial's commands and adjust according to your local machine's parameters.
|
||||
7. During the running process, check the memory usage. Observe its invocation through the top command. The memory capacity on a single CPU must be greater than the complete size of the model. (For multiple CPUs, it's just a copy.)
|
||||
Finally, confirm that the model is fully loaded into memory and specific weight layers are fully loaded into the GPU memory. Then, try to input content in the chat interface and observe if there are any errors.
|
||||
|
||||
Attention, for better perfomance, you can check this [method](https://github.com/kvcache-ai/ktransformers/issues/374#issuecomment-2667520838) in the issue
|
||||
>
|
||||
>https://github.com/kvcache-ai/ktransformers/blob/89f8218a2ab7ff82fa54dbfe30df741c574317fc/ktransformers/operators/attention.py#L274-L279
|
||||
>
|
||||
>```diff
|
||||
>+ original_dtype = query_states.dtype
|
||||
>+ target_dtype = torch.half
|
||||
>+ query_states = query_states.to(target_dtype)
|
||||
>+ compressed_kv_with_k_pe = compressed_kv_with_k_pe.to(target_dtype)
|
||||
>+ compressed_kv = compressed_kv.to(target_dtype)
|
||||
>+ attn_output = attn_output.to(target_dtype)
|
||||
>
|
||||
>decode_attention_fwd_grouped(query_states, compressed_kv_with_k_pe, compressed_kv, attn_output,
|
||||
> page_table,
|
||||
> position_ids.squeeze(0).to(torch.int32)+1, attn_logits,
|
||||
> 4, #num_kv_splits # follow vLLM, fix it TODO
|
||||
> self.softmax_scale,
|
||||
> past_key_value.page_size)
|
||||
>
|
||||
>+ attn_output = attn_output.to(original_dtype)
|
||||
>```
|
||||
>
|
||||
>https://github.com/kvcache-ai/ktransformers/blob/89f8218a2ab7ff82fa54dbfe30df741c574317fc/ktransformers/operators/attention.py#L320-L326
|
||||
>
|
||||
>```diff
|
||||
>- attn_output = flash_attn_func(
|
||||
>- query_states,
|
||||
>- key_states,
|
||||
>- value_states_padded,
|
||||
>- softmax_scale=self.softmax_scale,
|
||||
>- causal=True,
|
||||
>- )
|
||||
>+ attn_output = F.scaled_dot_product_attention(
|
||||
>+ query_states.transpose(1, 2),
|
||||
>+ key_states.transpose(1, 2),
|
||||
>+ value_states_padded.transpose(1, 2),
|
||||
>+ scale=self.softmax_scale,
|
||||
>+ is_causal=True
|
||||
>+ ).transpose(1, 2)
|
||||
>```
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
# ROCm Support for ktransformers (Beta)
|
||||
|
||||
## Introduction
|
||||
|
||||
### Overview
|
||||
In our effort to expand GPU architecture support beyond NVIDIA, we are excited to introduce **AMD GPU support through ROCm** in ktransformers (Beta release). This implementation has been tested and developed using EPYC 9274F processors and AMD Radeon 7900xtx GPUs.
|
||||
|
||||
## Installation Guide
|
||||
|
||||
### 1. Install ROCm Driver
|
||||
Begin by installing the ROCm drivers for your AMD GPU:
|
||||
- [Official ROCm Installation Guide for Radeon GPUs](https://rocm.docs.amd.com/projects/radeon/en/latest/docs/install/native_linux/install-radeon.html)
|
||||
|
||||
### 2. Set Up Conda Environment
|
||||
We recommend using Miniconda3/Anaconda3 for environment management:
|
||||
|
||||
```bash
|
||||
# Download Miniconda
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
|
||||
# Create environment
|
||||
conda create --name ktransformers python=3.11
|
||||
conda activate ktransformers
|
||||
|
||||
# Install required libraries
|
||||
conda install -c conda-forge libstdcxx-ng
|
||||
|
||||
# Verify GLIBCXX version (should include 3.4.32)
|
||||
strings ~/anaconda3/envs/ktransformers/lib/libstdc++.so.6 | grep GLIBCXX
|
||||
```
|
||||
|
||||
> **Note:** Adjust the Anaconda path if your installation directory differs from `~/anaconda3`
|
||||
|
||||
### 3. Install PyTorch for ROCm
|
||||
Install PyTorch with ROCm 6.2.4 support:
|
||||
|
||||
```bash
|
||||
pip3 install torch torchvision torchaudio \
|
||||
--index-url https://download.pytorch.org/whl/rocm6.2.4
|
||||
pip3 install packaging ninja cpufeature numpy
|
||||
```
|
||||
|
||||
> **Tip:** For other ROCm versions, visit [PyTorch Previous Versions](https://pytorch.org/get-started/previous-versions/)
|
||||
|
||||
### 4. Build ktransformers
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule update --init
|
||||
|
||||
# Optional: Compile web interface
|
||||
# See: api/server/website.md
|
||||
|
||||
# Install dependencies
|
||||
bash install.sh
|
||||
```
|
||||
|
||||
## Running DeepSeek-R1 Models
|
||||
|
||||
### Configuration for 24GB VRAM GPUs
|
||||
Use our optimized configuration for constrained VRAM:
|
||||
|
||||
```bash
|
||||
python ktransformers/local_chat.py \
|
||||
--model_path deepseek-ai/DeepSeek-R1 \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/rocm/DeepSeek-V3-Chat.yaml \
|
||||
--cpu_infer <cpu_cores + 1>
|
||||
```
|
||||
|
||||
> **Beta Note:** Current Q8 linear implementation (Marlin alternative) shows suboptimal performance. Expect optimizations in future releases.
|
||||
|
||||
### Configuration for 40GB+ VRAM GPUs
|
||||
For better performance on high-VRAM GPUs:
|
||||
|
||||
1. Modify `DeepSeek-V3-Chat.yaml`:
|
||||
```yaml
|
||||
# Replace all instances of:
|
||||
KLinearMarlin → KLinearTorch
|
||||
```
|
||||
|
||||
2. Execute with:
|
||||
```bash
|
||||
python ktransformers/local_chat.py \
|
||||
--model_path deepseek-ai/DeepSeek-R1 \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path <modified_yaml_path> \
|
||||
--cpu_infer <cpu_cores + 1>
|
||||
```
|
||||
> **Tip:** If you got 2 * 24GB AMD GPUS, you may also do the same modify and run `ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu.yaml` instead.
|
||||
|
||||
## Known Limitations
|
||||
- Marlin operations not supported on ROCm platform
|
||||
- Current Q8 linear implementation shows reduced performance (Beta limitation)
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
## Hello everyone, here is the successfully reproduced environment configuration for your reference:
|
||||
### Case 1
|
||||
- Configuration: l40s 48G + 9654 x2 (192 cores) + 768G DDR5 12-channel
|
||||
- Performance: prefill 108 tokens/s, decode 10.8 tokens/s
|
||||
- Used version: main source code compiled
|
||||
### Case 2
|
||||
- Configuration: Dual Xeon 6430 32C processors, totaling 64 cores and 128 threads, 480GB DDR5 memory, single 4090 24G graphics card
|
||||
- Performance: Running speed approximately 6-8 tokens per second
|
||||
## NOTE
|
||||
If there are any other configurations that have been successfully run, please feel free to let us know. We will keep updating for everyone to refer to when reproducing. (It has been found that it also works on 2080, AMD, etc. (doge : )
|
||||
[click here](https://docs.qq.com/smartsheet/form/AVxgQOYhhNfl%2FBB08J2%2Fv3rnnq?tab=BB08J2)
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
# API
|
||||
|
||||
- [OpenAI ChatCompletion](#openai-chatcompletion)
|
||||
- [Ollama ChatCompletion](#ollama-chatcompletion)
|
||||
- [OpenAI Assistant](#openai-assistant)
|
||||
|
||||
## OpenAI ChatCompletion
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
|
||||
```
|
||||
Generate responses based on the selected model.
|
||||
|
||||
### Parameters
|
||||
- `messages`: An array of `message` representing all historical messages. A `message` can be from a user or model (assistant) and includes:
|
||||
|
||||
- `role`: Either `user` or `assistant`, indicating the creator of this message.
|
||||
- `content`: The message from the user or model.
|
||||
- `model`: The name of the selected model
|
||||
- `stream`: Either true or false. Indicates whether to use streaming response. If true, model inference results are returned via HTTP event stream.
|
||||
|
||||
### Response
|
||||
- Streaming response: An event stream, each event contains a `chat.completion.chunk`. `chunk.choices[0].delta.content` is the incremental output returned by the model each time.
|
||||
- Non-streaming response: Not supported yet.
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
```bash
|
||||
curl -X 'POST' \
|
||||
'http://localhost:9112/v1/chat/completions' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"messages": [
|
||||
{
|
||||
"content": "tell a joke",
|
||||
"role": "user"
|
||||
}
|
||||
],
|
||||
"model": "Meta-Llama-3-8B-Instruct",
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
```bash
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"Why ","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"couldn't ","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
...
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"two-tired!","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
event: done
|
||||
data: [DONE]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Ollama ChatCompletion
|
||||
|
||||
```bash
|
||||
POST /api/generate
|
||||
```
|
||||
|
||||
Generate responses using the selected model.
|
||||
|
||||
### Parameters
|
||||
- `prompt`: A string representing the input prompt.
|
||||
- `model`: The name of the selected model
|
||||
- `stream`: Either true or false. Indicates whether to use streaming responses. If true, returns the model inference results in the form of an HTTP event stream.
|
||||
|
||||
### Response
|
||||
- Streaming response: A stream of JSON responses, each line is a JSON.
|
||||
- `response`: The incremental result of the model completion.
|
||||
- `done`: Whether the inference has finished.
|
||||
- Non-streaming response: Not yet supported.
|
||||
|
||||
### 例子
|
||||
|
||||
```bash
|
||||
curl -X 'POST' \
|
||||
'http://localhost:9112/api/generate' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"model": "Meta-Llama-3-8B-Instruct",
|
||||
"prompt": "tell me a joke",
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
```bash
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:11.686513","response":"I'll ","done":false}
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:11.729214","response":"give ","done":false}
|
||||
|
||||
...
|
||||
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:33.955475","response":"for","done":false}
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:33.956795","response":"","done":true}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
|
@ -1,37 +0,0 @@
|
|||
# Backend Services (Server)
|
||||
The Server offers fast heterogeneous inference capabilities of ktransformers through an API for external usage.
|
||||
|
||||
<img src="server-arch.png" height="600" alt="Server architecture">
|
||||
|
||||
## API
|
||||
|
||||
The Server provides model inference services externally through a RESTful API, with two methods of interaction: ChatCompletion and Assistant.
|
||||
|
||||
- The ChatCompletion interface requires users to provide all historical dialogues at once, after which the model responds. AI service providers (such as [OpenAI](https://platform.openai.com/docs/api-reference/chat/create)) and local inference frameworks (such as [Ollama](https://github.com/ollama/ollama/blob/main/docs/api.md)) both offer the ChatCompletion interface. To ensure compatibility with OpenAI and Ollama, the Server offers APIs that are consistent with theirs. Therefore, applications currently using OpenAI and Ollama can seamlessly switch to our Server. For example: [How to use Tabby and ktransformers locally with a 236B model for code completion?](tabby.md).
|
||||
- The Assistant is suitable for applications that need to reuse a series of resources and call the model. For instance, in educational applications, developers can create an Assistant named "Second Grade Math Teacher" and set an initial prompt ("You are an experienced second-grade math teacher..."), and upload relevant materials (second grade math textbooks). After creating the Assistant, the application needs to create a Thread to store the dialogues between the user and the model (Message). When calling the model, the application creates a Run to obtain the Assistant's response. Compared to ChatCompletion, the Assistant-enabled Server handles the reuse of conversational contexts and multi-turn dialogues, making model calls in complex scenarios more convenient. The [OpenAI Assistant API](https://platform.openai.com/docs/api-reference/assistants/createAssistant) introduces such an Assistant interface, and the Server provides a consistent API.
|
||||
|
||||
These API definitions are located in `server/api`, and their specific usage can be seen [here](api.md).
|
||||
|
||||
## Integrating Model Inference Frameworks
|
||||
|
||||
The Server uses ktransformers for model calling and inference. It also supports other inference frameworks, such as the already supported [transformers](https://huggingface.co/docs/transformers/index), and plans to support [exllamav2](https://github.com/turboderp/exllamav2). These functionalities are implemented in `server/backend`.
|
||||
|
||||
The model inference functionalities of the frameworks are abstracted into a base class `BackendInterfaceBase`. This class includes a function: inference. It takes historical dialogue information messages as input and returns the text result from the model. The inference function adopts an async generator design, allowing the Server to return model responses in a streaming manner.
|
||||
|
||||
```python
|
||||
class BackendInterfaceBase:
|
||||
async def inference(self, messages, **kwargs)->AsyncIterator[str]:
|
||||
...
|
||||
```
|
||||
|
||||
This inference function naturally implements the functionality of ChatCompletion because its inputs and outputs are historical dialogues and model responses, respectively. Thus, the ChatCompletion API can directly call the inference function to complete model inference.
|
||||
|
||||
Assistant is more complex than ChatCompletion, requiring the Server to store the related state of the Assistant and call the inference function appropriately. The Server maintains a set of Assistant logic in the database, storing the Assistants, Threads, and Messages created by applications. In memory, the Server maintains a `ThreadContext` for each Thread, gathering information related to each Thread's Assistant, etc. When a user sends a new Message, the Server calls the get_local_messages function of ThreadContext to obtain messages and then calls the inference function to get the inference results.
|
||||
|
||||
```python
|
||||
class MyThreadContext(ThreadContext):
|
||||
def get_local_messages(self):
|
||||
...
|
||||
```
|
||||
|
||||
Since different model inference frameworks have different historical dialogue input formats, `ThreadContext` and `BackendInterface` need to be used in pairs. Besides its own ktransformers, the Server also supports transformers. For integrating other model inference frameworks, refer to the implementations of `TransformersInterface` and `TransformersThreadContext` in [transformers.py](https://github.com/kvcache-ai/ktransformers-dev/blob/main/ktransformers/server/backend/interfaces/transformers.py).
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
# How to Use Tabby and ktransformers Locally with 236B Large Models for Code Completion?
|
||||
|
||||
[Tabby](https://tabby.tabbyml.com/docs/welcome/) is an open-source code assistant that allows users to manually configure the backend framework and model, and use it across multiple IDEs/editors, such as VSCode and IntelliJ. Since Tabby can interface with Ollama on the framework side, and the ktransformers server provides a consistent API with Ollama, we can connect Tabby to the ktransformers server. This setup allows us to experience fast, heterogeneous inference in code completion scenarios.
|
||||
|
||||
1. Start ktransformers.
|
||||
```bash
|
||||
./ktransformers --port 9112
|
||||
```
|
||||
2. Install Tabby: Follow the official tutorial to install Tabby on a Linux server or Windows PC with an NVIDIA GPU [here](https://tabby.tabbyml.com/docs/quick-start/installation/linux/).
|
||||
3. Configure Tabby: Create `~/.tabby/config.toml` and add the following configuration.
|
||||
```toml
|
||||
[model.completion.http]
|
||||
kind = "ollama/completion"
|
||||
api_endpoint = "http://127.0.0.1:9112/"
|
||||
model_name = "DeepSeek-Coder-V2-Instruct"
|
||||
prompt_template = "<|fim▁begin|>{prefix}<|fim▁hole|>{suffix}<|fim▁end|>" # Prompt Template
|
||||
```
|
||||
|
||||
In this configuration, `kind` specifies that ktransformers uses the standard Ollama API to serve Tabby; `api_endpoint` matches the interface bound when launching ktransformers; `model_name` is set to the model used by ktransformers, here `DeepSeek-Coder-V2-Instruct` is the backend inference model; `prompt_template` is the model's prompt template, which requires a corresponding template for different models to use the Fill In the Middle feature properly.
|
||||
Here we demonstrate the relevant configuration for Tabby using the Ollama API to provide the Completion feature. For configuration information about other functions available in Tabby, refer to [here](https://tabby.tabbyml.com/docs/administration/model/).
|
||||
|
||||
|
||||
4. Start the Tabby service: `./tabby serve`.
|
||||
<img src="run-tabby.png" alt="image-20240709112329577" style="zoom:50%;" />
|
||||
|
||||
After launching, you should see access to the `/api/tags` interface in the ktransformers command line (in version v0.13.0 of Tabby, this changes to access to the `/api/show/` interface).
|
||||
<img src="visit-api-tags.png" alt="image-20240709111648215" style="zoom:67%;" />
|
||||
|
||||
6. Register a Tabby account, obtain a Token: After starting the Tabby service, open the corresponding link in a browser (as shown above at 0.0.0.0:8080), and follow the [tutorial](https://tabby.tabbyml.com/docs/quick-start/register-account/) to create a user and get a Token.
|
||||
|
||||
7. Start VSCode, install the Tabby extension plugin, and use the Token obtained in the previous step to connect to the Tabby Server, following [here](https://tabby.tabbyml.com/docs/extensions/installation/vscode/).
|
||||
|
||||
8. Open any code file and experience the fast heterogeneous inference of ktransformers.
|
||||
|
Before Width: | Height: | Size: 57 KiB |
|
|
@ -1,46 +0,0 @@
|
|||
# Start with website
|
||||
|
||||
This document provides the necessary steps to set up and run the web service for this project.
|
||||
|
||||
## 1. Starting the Web Service
|
||||
|
||||
### 1.1. Compiling the Web Code
|
||||
|
||||
Before you can compile the web code, make sure you have installed [Node.js](https://nodejs.org) version 18.3 or higher
|
||||
|
||||
Note: The version of Node.js in the Ubuntu or Debian GNU/Linux software repository is too low, causing compilation errors. Users can also install Node.js through the Nodesource repository, provided they uninstall the outdated version first.
|
||||
|
||||
```bash
|
||||
|
||||
# sudo apt-get remove nodejs npm -y && sudo apt-get autoremove -y
|
||||
sudo apt-get update -y && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
|
||||
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /usr/share/keyrings/nodesource.gpg
|
||||
sudo chmod 644 /usr/share/keyrings/nodesource.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_23.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install nodejs -y
|
||||
|
||||
```
|
||||
|
||||
Once npm is installed, navigate to the `ktransformers/website` directory:
|
||||
|
||||
```bash
|
||||
cd ktransformers/website
|
||||
```
|
||||
|
||||
Next, install the Vue CLI with the following command:
|
||||
|
||||
```bash
|
||||
npm install @vue/cli
|
||||
```
|
||||
|
||||
Now you can build the project:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
Finally you can build ktransformers with website:
|
||||
```
|
||||
cd ../../
|
||||
pip install .
|
||||
```
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
# Balance Serve backend (multi-concurrency) for ktransformers
|
||||
|
||||
## KTransformers v0.2.4 Release Notes
|
||||
|
||||
We are excited to announce the official release of the long-awaited **KTransformers v0.2.4**!
|
||||
In this version, we’ve added highly desired **multi-concurrency** support to the community through a major refactor of the whole architecture, updating more than 10,000 lines of code.
|
||||
By drawing inspiration from the excellent architecture of sglang, we have implemented high-performance asynchronous concurrent scheduling in C++, including features like continuous batching, chunked prefill, and more. Thanks to GPU sharing in concurrent scenarios, overall throughput is also improved to a certain extent. The following is a demonstration:
|
||||
|
||||
https://github.com/user-attachments/assets/faa3bda2-928b-45a7-b44f-21e12ec84b8a
|
||||
|
||||
</p>
|
||||
|
||||
### 🚀 Key Updates
|
||||
|
||||
1. Multi-Concurrency Support
|
||||
- Added capability to handle multiple concurrent inference requests. Supports receiving and executing multiple tasks simultaneously.
|
||||
- We implemented [custom_flashinfer](https://github.com/kvcache-ai/custom_flashinfer/tree/fix-precision-mla-merge-main) based on the high-performance and highly flexible operator library [flashinfer](https://github.com/flashinfer-ai/flashinfer/), and achieved a variable batch size CUDA Graph, which further enhances flexibility while reducing memory and padding overhead.
|
||||
- In our benchmarks, overall throughput improved by approximately 130% under 4-way concurrency.
|
||||
- With support from Intel, we tested KTransformers v0.2.4 on the latest Xeon6 + MRDIMM-8800 platform. By increasing concurrency, the total output throughput increased from 17 tokens/s to 40 tokens/s. We observed that the bottleneck has now shifted to the GPU. Using a higher-end GPU than the 4090D could further improve performance.
|
||||
2. Engine Architecture Optimization
|
||||

|
||||
Inspired by the scheduling framework of sglang, we refactored KTransformers with a clearer three-layer architecture through an update of 11,000 lines of code, now supporting full multi-concurrency:
|
||||
- Server:Handles user requests and serves the OpenAI-compatible API.
|
||||
- Inference Engine:Executes model inference and supports chunked prefill.
|
||||
- Scheduler:Manages task scheduling and requests orchestration. Supports continuous batching by organizing queued requests into batches in a FCFS manner and sending them to the inference engine.
|
||||
3. Project Structure Reorganization
|
||||
All C/C++ code is now centralized under the /csrc directory.
|
||||
4. Parameter Adjustments
|
||||
Removed some legacy and deprecated launch parameters for a cleaner configuration experience.
|
||||
We plan to provide a complete parameter list and detailed documentation in future releases to facilitate flexible configuration and debugging.
|
||||
|
||||
### 📚 Upgrade Notes
|
||||
|
||||
- Due to parameter changes, users who have installed previous versions are advised to delete the ~/.ktransformers directory and reinitialize.
|
||||
- To enable multi-concurrency, please refer to the latest documentation for configuration examples.
|
||||
|
||||
### What's Changed
|
||||
|
||||
Implemented **custom_flashinfer** @Atream @ovowei @qiyuxinlin
|
||||
Implemented **balance_serve** engine based on **FlashInfer** @qiyuxinlin @ovowei
|
||||
Implemented a **continuous batching** scheduler in C++ @ErvinXie
|
||||
release: bump version v0.2.4 by @Atream @Azure-Tang @ErvinXie @qiyuxinlin @ovowei @KMSorSMS @SkqLiao
|
||||
|
||||
## Download the Docker image for testing v0.2.4
|
||||
Visit the [link](https://hub.docker.com/r/approachingai/ktransformers/tags) to pull the image, using `v0.2.4-AVX512` as an example.
|
||||
|
||||
```bash
|
||||
docker pull approachingai/ktransformers:v0.2.4-AVX512
|
||||
docker run -it --gpus all --privileged --shm-size 64g --name ktrans --network=host -v /mnt:/mnt approachingai/ktransformers:v0.2.4-AVX512 /bin/bash
|
||||
# Open a new terminal
|
||||
docker exec -it ktrans bash
|
||||
```
|
||||
|
||||
## Installation Guide
|
||||
|
||||
⚠️ Please note that installing this project will replace flashinfer in your environment. It is strongly recommended to create a new conda environment!!!
|
||||
|
||||
⚠️ Please note that installing this project will replace flashinfer in your environment. It is strongly recommended to create a new conda environment!!!
|
||||
|
||||
⚠️ Please note that installing this project will replace flashinfer in your environment. It is strongly recommended to create a new conda environment!!!
|
||||
|
||||
### 2. Set Up Conda Environment
|
||||
|
||||
We recommend using Miniconda3/Anaconda3 for environment management:
|
||||
|
||||
```bash
|
||||
# Download Miniconda
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
|
||||
# Create environment
|
||||
conda create --name ktransformers python=3.11
|
||||
conda activate ktransformers
|
||||
|
||||
# Install required libraries
|
||||
conda install -c conda-forge libstdcxx-ng
|
||||
|
||||
# Verify GLIBCXX version (should include 3.4.32)
|
||||
strings ~/anaconda3/envs/ktransformers/lib/libstdc++.so.6 | grep GLIBCXX
|
||||
```
|
||||
|
||||
> **Note:** Adjust the Anaconda path if your installation directory differs from `~/anaconda3`
|
||||
|
||||
### 2. Install dependencies
|
||||
|
||||
```bash
|
||||
sudo apt install libtbb-dev libssl-dev libcurl4-openssl-dev libaio1 libaio-dev libfmt-dev libgflags-dev zlib1g-dev patchelf
|
||||
pip3 install packaging ninja cpufeature numpy openai
|
||||
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
|
||||
|
||||
```
|
||||
|
||||
### 3. Build ktransformers
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule update --init --recursive
|
||||
|
||||
|
||||
# Install single NUMA dependencies
|
||||
USE_BALANCE_SERVE=1 bash ./install.sh
|
||||
# For those who have two cpu and 1T RAM(Dual NUMA):
|
||||
USE_BALANCE_SERVE=1 USE_NUMA=1 bash ./install.sh
|
||||
```
|
||||
|
||||
## Running DeepSeek-R1-Q4KM Models
|
||||
|
||||
### 1. Run for 24GB VRAM GPUs
|
||||
|
||||
Use our optimized configuration for constrained VRAM:
|
||||
|
||||
```bash
|
||||
python ktransformers/server/main.py \
|
||||
--port 10002 \
|
||||
--model_path <path_to_safetensor_config> \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-serve.yaml \
|
||||
--max_new_tokens 1024 \
|
||||
--cache_lens 32768 \
|
||||
--chunk_size 256 \
|
||||
--max_batch_size 4 \
|
||||
--backend_type balance_serve \
|
||||
--force_think # useful for R1
|
||||
```
|
||||
|
||||
It features the following arguments:
|
||||
|
||||
- `--max_new_tokens`: Maximum number of tokens generated per request.
|
||||
- `--cache_lens`: Total length of kvcache allocated by the scheduler. All requests share a kvcache space.
|
||||
- `--max_batch_size`: Maximum number of requests (prefill + decode) processed in a single run by the engine. (Supported only by `balance_serve`)
|
||||
- `--chunk_size`: Maximum number of tokens processed in a single run by the engine.
|
||||
corresponding to 32768 tokens, and the space occupied will be released after the requests are completed.
|
||||
- `--backend_type`: `balance_serve` is a multi-concurrency backend engine introduced in version v0.2.4. The original single-concurrency engine is `ktransformers`.
|
||||
- `--model_path`: Path to safetensor config path (only config required, not model safetensors).
|
||||
Please note that, since `ver 0.2.4`, the last segment of `${model_path}` directory name **MUST** be a local directory that contains the model's configuration files. Hugging Face links (e.g., deepseek-ai/DeepSeek-R1) are not supported at the moment.
|
||||
- `--force_think`: Force responding the reasoning tag of `DeepSeek R1`.
|
||||
|
||||
The relationship between `max_batch_size`, `cache_lens`, and `max_new_tokens` should satisfy:
|
||||
`cache_lens > max_batch_size * max_new_tokens`, otherwise the concurrency will decrease.
|
||||
|
||||
### 2. access server
|
||||
|
||||
```
|
||||
curl -X POST http://localhost:10002/v1/chat/completions \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"messages": [
|
||||
{"role": "user", "content": "hello"}
|
||||
],
|
||||
"model": "DeepSeek-R1",
|
||||
"temperature": 0.3,
|
||||
"top_p": 1.0,
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
## Benchmark
|
||||
|
||||
To conduct a quick and convenient check, we have employed a simple Python script available [here](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/tests) to assess the precision of our **[ktransformers](https://github.com/kvcache-ai/ktransformers)** project. For this evaluation, we utilized the same dataset, which was shuffled in a consistent manner and limited to the first 1,000 data points, to test our implementation across a variety of CPU kernels, MLA kernels, and quantization formats.
|
||||
|
||||
We selected the DeepSeek-V3 model in its bf16, int8, and q4km versions for this test. The MMLU dataset, which can be found [here](https://huggingface.co/datasets/cais/mmlu), was used (we selected all datasets and shuffled them with a fixed random seed).
|
||||
|
||||
**!!! However, we skipped the few-shot part and only chose the first 1,000 data points for a quick check.** Please note that this approach may result in results that are not consistent with the technical report of DeepSeek-V3. And the test of R1 and further more tests are on going.
|
||||
|
||||
To verify our results, we chose [cloud service platform](https://cloud.siliconflow.cn/models) as baseline. All tests were conducted using the same script and datasets, allowing us to make a preliminary assessment of our project's precision.
|
||||
|
||||
We set the argument `temperature=0.6`, and to simplify the test process, we skipped the few-shot part and used the following prompt: `There is a single choice question. Answer the question by replying A, B, C, D. No other answers are accepted. Just the letter. \nQuestion: {question}\nA. {option_a}\nB. {option_b}\nC. {option_c}\nD. {option_d}\nAnswer: '`. For more details, please refer to the [script](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/tests/mmlu_test.py).
|
||||
|
||||
Given that we have only tested 1,000 cases, which provides only a preliminary judgment, some fluctuations in the results are reasonable. We selected all datasets and shuffled them with a fixed random seed to ensure consistency.
|
||||
|
||||
## Some Details
|
||||
|
||||
- The bf16 model of DeepSeek-V3 is available [here](https://huggingface.co/opensourcerelease/DeepSeek-V3-bf16/tree/main) (you may convert it to gguf by llama.cpp). The q4km model can be found [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M).
|
||||
|
||||
- The optimization YAML file is located [here](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/optimize/optimize_rules). For the GEMM Kernel, you can change `KLinearMarlin` to `KLinearTorch`.
|
||||
|
||||
- To switch the MLA Kernel from Triton to Torch, you can check and modify [this file](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/attention.py), specifically by using the `forward_windows` method.
|
||||
|
||||
- When attempting to conduct the bf16 test (both CPU Weight and GPU Weight), you may encounter issues stemming from older versions of g++ and as, particularly when using Ubuntu 20 or earlier versions. To facilitate a smoother experience and enable you to reproduce our results, we have provided a development container. This container offers a pre-configured environment tailored for this purpose. However, please note that the container does not have the ktrans package installed. Therefore, you may still need to manually install certain packages to ensure everything runs smoothly.
|
||||
|
||||
- You may config the model mount dir in `devcontainer/devcontainer.json`, check the `"mouts":` config.
|
||||
|
||||
|
||||
## The Result Table
|
||||
Uses DeepSeek-V3 model (Some specific cases are R1)
|
||||
| | | | | | | | |
|
||||
| ------------------------ | ----------------- | ---------- | ----------------- | ------- | ---------- | ------------------------------------------------------ | ------------ |
|
||||
| DataSet | CPU Weight Format | CPU Kernel | GPU Weight Format | GEMM Kernel | MLA Kernel | [Siliconflow](https://cloud.siliconflow.cn/models)<br> | Ktrans Point |
|
||||
| MMLU<br><br>(shuffle 1k) | | | | | | | |
|
||||
| 1 | bf16 | cpuinfer | bf16 | torch | torch | 81.6 | 81.9 |
|
||||
| 2 | q8_0 | cpuinfer | bf16 | torch | torch | 81.6 | 83.1 |
|
||||
| 3 | q4km | cpuinfer | bf16 | torch | triton | 81.6 | 81.4 |
|
||||
| 4 | q4km | cpuinfer | q4km->marlin 8 | marlin | triton | 81.6 | 81.1 |
|
||||
| 5 | q4km | cpuinfer | q4km->marlin 4 | marlin | triton | 81.6 | 81 |
|
||||
| 6 | q4km | cpuinfer | fp8 | fp8gemm | triton | 81.6 | 81.5 |
|
||||
| 7 (DeepSeek-R1) | iq1 | cpuinfer | fp8 | fp8gemm | triton | 78.6 | 83.6 |
|
||||
| MMLU-pro<br>(shuffle 1k) | | | | | | | |
|
||||
| 1 | q4km | cpuinfer | fp8 | fp8gemm | triton | 57.7 | 57.6 |
|
||||
| 2 | q4km | cpuinfer | q4km->marlin 4 | marlin | triton | 57.7 | 57.5 |
|
||||
| 3 (DeepSeek-R1) | iq1 | cpuinfer | fp8 | fp8gem | triton | 71.9 | tbd |
|
||||
| HumanEval | tbd | tbd | tbd | tbd | tbd | tbd | tbd |
|
||||
| GSM8K | tbd | tbd | tbd | tbd | tbd | tbd | tbd |
|
||||
|
||||
**The details for each case are listed below**:
|
||||
|
||||
By default, The MLA kernel uses triton in linux and torch in windows. But we need to test torch in linux, so we manually modify the [file](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/attention.py#L592). Just get rid of all the if branch and force it to use `self.forward_windows`
|
||||
|
||||
- MMLU test
|
||||
1. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml) change all the `KLinearMarlin` to `KLinearTorch` (just find all the usage in this file). The source weight comes from [there](https://huggingface.co/opensourcerelease/DeepSeek-V3-bf16) (you need to use llama.cpp to convert it to gguf)
|
||||
2. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml). You need to modify the code to separately load cpu's expert weight. We leave this as comment in these places: [1](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L122), [2](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L136), [3](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L137) (note in 3, change the path to your local weight file path). The weight file for q8_0 is [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q8_0)
|
||||
3. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml). You need to modify the code to separately load cpu's expert weight. We leave this as comment in these places: [1](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L122), [2](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L136), [3](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/operators/experts.py#L137) (note in 3, change the path to your local weight file path). The weight file for q4km is [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M)
|
||||
4. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml). You don't need to change the source code as they both use q4km. But note the yaml file [here](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml#L29) and [here](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml#L18), below these lines you need to add `num_bits: 8` (in other words: add this kwargs to all that use `KLinearMarlin`). The weight file for q4km is [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M)
|
||||
5. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml). No need to change yaml, just use the default. The weight file for q4km is [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M)
|
||||
6. You should check the [doc](./fp8_kernel.md) to learn how to test this case. This is a mixture tensor case.
|
||||
7. You should check the [doc](./fp8_kernel.md) to learn how to test this case. This is a mixture tensor case.
|
||||
- MMLU-pro test
|
||||
1. You should check the [doc](./fp8_kernel.md) to learn how to test this case. This is a mixture tensor case.
|
||||
2. [v3-chat_yaml](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat.yaml). No need to change yaml, just use the default. The weight file for q4km is [here](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M)
|
||||
3. You should check the [doc](./fp8_kernel.md) to learn how to test this case. This is a mixture tensor case.
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
# Tutorial: Heterogeneous and Local MoE Inference
|
||||
|
||||
DeepSeek-(Code)-V2 is a series of strong mixture-of-experts (MoE) models, featuring a total of 236 billion parameters, with 21 billion parameters activated per token. This model has demonstrated remarkable reasoning capabilities across various benchmarks, positioning it as one of the SOTA open models and nearly comparable in performance to GPT-4. DeepSeek-R1 uses a similar architecture to DeepSeek-V2, but with a bigger number of parameters.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="DeepSeek-Coder-V2 Score" src="../assets/BigCodeBench.png" width=80%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
Moreover, unlike previous models that employed traditional attention mechanisms like Grouped-Query Attention (GQA), DeepSeek-V2 incorporates a novel Multi-head Latent Attention (MLA). This innovation significantly reduces the size of the KV cache required during inference, enhancing efficiency.
|
||||
|
||||
|
||||
However, despite its efficiency, the practicality of running such a large model on personal computing setups seems impractical. Official documentation for DeepSeek-V2 indicates that eight 80GB GPUs are necessary for standard inference operations, and even the scaled-down Q4_k_m version requires at least two 80GB GPUs. These requirements are beyond the reach of most individual researchers and small teams.
|
||||
|
||||
|
||||
Nonetheless, by employing several cutting-edge optimization techniques, we have successfully operated this colossal model on a desktop computer with only 21GB of VRAM and 136GB of DRAM. In this document, we outline the specific optimizations utilized and provide a detailed tutorial on how to implement these strategies using KTransformers.
|
||||
|
||||
## Applied Optimizations
|
||||
|
||||
### Optimized MLA Operator
|
||||
|
||||
The following figure provides a brief overview of DeepSeek-V2 architecture. At the heart of its attention layer, DeepSeek-V2 introduces a novel MLA operator that represents the heads of key-value pairs using a common, joint compressed representation, which holds significant potential for efficiency improvements. However, the official open-source implementation of the MLA operator explicitly decompresses this compressed representation and caches the decompressed key-value pairs. This process not only enlarges the KV cache size but also diminishes inference performance.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="DeepSeek on KTransformers" src="../assets/DeepSeek-on-KTransformers.png" width=80%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
To truly capitalize on the benefits of MLA, we have implemented an optimized version for inference. According to its original paper, we absorb the decompression matrices directly into the q_proj and out_proj weights. Consequently, the compressed representation does not need to be decompressed to compute the attention. This adjustment significantly reduces the KV cache size and increases the arithmetic intensity of this operator, which greatly optimizes the utilization of GPU computational power.
|
||||
|
||||
### Advanced Quantization Kernels
|
||||
|
||||
The original DeepSeek-V2 model stores its parameters in BF16 format, consuming approximately 470GB of raw storage. This exceeds the RAM capacity available on mainstream desktop computers. To address this, we leverage the well-established GGUF community's quantized weights to simplify the process for users.
|
||||
However, quantized data types are not typically supported by highly-optimized BLAS packages. As a result, the original HuggingFace Transformers' Torch implementation must dequantize these tensors to supported data types before processing, which introduces unnecessary computational overhead and increases memory traffic. To overcome this, we have incorporated advanced kernels that operate directly on quantized data types, thereby optimizing inference performance.
|
||||
|
||||
|
||||
In the current version of KTransformers, we utilize Marlin for GPU kernels and llamafile for CPU kernels. These kerenls are specially designed to benefit from modern GPU architecture and modern CPU instruction extensions such as AVX512-BF16 (AMD Zen4 or newer) and AVX-VNNI (Intel Alder Lake or newer), that are tailored for quantized data types and machine learning workloads. We also use expert parallelism and other optimization for MOE inferencem on CPU based on llamafile, and call them as CPUInfer. As demonstrated in Figure 2(cite from Marlin), Marlin can achieve near ideal 3.87x speedup compare to corresponding Torch counterparts. As demonstrated in the following figure, our micro benchmarks show that inference using CPUInfer performs several times faster than Torch in low bits representation. Note that in practical inference such as using transformers, the Torch baseline use BF16 or FP16 as linear weights, and will occupy more memory resources, or it will be more slower due to dequantization when using quanted weights.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="CPUInfer Performance" src="../assets/cpuinfer.png" width=80%>
|
||||
</picture>
|
||||
</p>
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="marlin performance" src="https://github.com/IST-DASLab/marlin/blob/master/assets/sustained.png?raw=true" width=80%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
### Arithmetic Intensity Guided Offloading
|
||||
|
||||
Storing all 236 billion parameters of a model in GPU VRAM is clearly impractical for local users. Therefore, we strategically store only the most computationally intensive parameters on the GPU. For instance, after our optimizations, the MLA operator, which contains 128 heads with a shared compressed key-value representation, shows an arithmetic intensity of 512. This makes it the most intensive operator, particularly during smaller inference batch sizes. Hence, it is allocated to the GPU to leverage the power of tensor cores.
|
||||
|
||||
|
||||
On the other hand, as shown in Figure 1, each transformer block in DeepSeek-V2 includes 160 mixture-of-experts (MoE) experts, comprising 96% of the total parameters. However, the MoE router activates only 6 out of these 160 experts for each token, which means that only 3.75% of the MoE parameters are utilized during the decoding phase. With a batch size of one, the arithmetic intensity of the MoE operation is roughly 0.075. This operation, primarily involving a batched General Matrix-Vector Multiplication (GEMV), can thus be efficiently handled by the CPU.
|
||||
|
||||
|
||||
Following this principle of arranging all operators by their arithmetic intensity and placing the most intensive ones in the GPU as much as possible, we prioritize positioning the MoE parameters and word embeddings computations on the CPU side to utilize its larger memory capacity. Meanwhile, the remaining parameters, including shared experts, projections in the attention module, and MLA, are stored in the GPU VRAM. As these parameters are accessed by every token, their placement on the GPU maximizes the benefits of high memory bandwidth. This configuration leads to approximately 20.7 GB of VRAM usage and 136GB DRAM memory requests if the Q4_K_M version is used, which is feasible even on a local desktop. Additionally, the placement can be adjusted according to the actual configuration, adhering to the same principle.
|
||||
|
||||
|
||||
Moreover, as an extensible framework, KTransformers is set to support more advanced operators in future releases, continually enhancing its capability to handle diverse workloads efficiently.
|
||||
|
||||
## YAML Template
|
||||
|
||||
To implement the above optimizations in KTransformers, users need to write a YAML file containing the optimized rules.
|
||||
KTransformers will iterate through all sub-modules of the model, match rules specified in the YAML rule file, and replace them with advanced modules as specified.
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="../assets/InjectStruction.png" width=80%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
Specifically, the following rules are used:
|
||||
|
||||
- Replace the Attention module with our [optimized MLA Operator](#mla).
|
||||
- Replace routed experts with [CPUInfer kernels](#experts) that use Llamafile.
|
||||
- Replace all Linear modules not belonging to attention with [Marlin](#linear) kernels.
|
||||
|
||||
|
||||
|
||||
<h3 id="mla">MLA</h3>
|
||||
|
||||
For attention module injection, we only need to match the module name used in Transformers using a regular expression and replace it with our pre-implemented module.
|
||||
The YAML rule is listed below.
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.self_attn$" # regular expression
|
||||
replace:
|
||||
class: ktransformers.operators.attention.KDeepseekV2Attention # optimized MLA implementation
|
||||
```
|
||||
|
||||
As we can see, each rule in the YAML file has two parts: `match` and `replace`.
|
||||
The match part specifies which module should be replaced, and the replace part specifies the module to be injected into the model along with the initialization keywords.
|
||||
|
||||
<h3 id="experts">Routed Experts </h3>
|
||||
|
||||
For routed experts, the module we inject is a wrapper of CPUInfer, KTransformersExperts. There are several implementations within a wrapper, and we need to specify keywords to tell the wrapper which implementation we want to use and how we intend to use it.
|
||||
|
||||
In KTransformers, some models exhibit different behaviors during prefilling and generation for better performance. KTransformersExperts is one of them. All these special modules have a `device` keyword describing which device the module should be initialized on. Other keywords specify the behaviors during prefilling and generation and may be differ when using different injection modules. Here, we specify which implementation on which device we want to use during prefilling and generation, and which device the output should be on.
|
||||
Note that we only use these parameters when layer-wise prefilling is enabled; otherwise, prefilling is conducted with the same configuration as generation.
|
||||
|
||||
In the original implementation of Transformers, MoE is implemented using `nn.ModuleList`. We don't want KTransformers to iterate through all the sub-modules in the list, so we set `recursive: False` in this rule to prevent recursive injection into submodules of the current module. Here is the YAML rule:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert parallelism
|
||||
device: "cpu" # device to load this module on initialization
|
||||
kwargs:
|
||||
prefill_device: "cuda"
|
||||
prefill_op: "KExpertsTorch"
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda"
|
||||
recursive: False # don't recursively inject submodules of this module
|
||||
```
|
||||
|
||||
If we inject the expert list as a custom module, we can't use the interface in `nn.ModuleList` as default. We need to change the forward function in the FFN module. The simplest way is implementing a new module using custom forward function and inject it. We have implemented the new module, and the injection can be done by simply adding an injection rule. We can use the `class` instead of `name` to match a module that will be replaced. Here is the YAML rule:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
class: ktransformers.models.modeling_deepseek.DeepseekV2MoE
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KDeepseekV2MoE # MLP module with custom forward function
|
||||
```
|
||||
|
||||
<h3 id="linear">Other Linear Modules</h3>
|
||||
|
||||
For the remained linear modules, we want to use our quantization kernels. However, we don't want to inject linear in the MLA operator because we currently don't know the effect of using quantization in MLA.
|
||||
So, we can change our regular expression and add a class check in the match part of the rule. Only modules matching both name and class simultaneously will be injected.
|
||||
We also need to transfer some keywords similar to the injection of experts. Here is the YAML rule:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\.(?!.*self_attn).*$" # regular expression
|
||||
class: torch.nn.Linear # only match modules matching name and class simultaneously
|
||||
replace:
|
||||
class: ktransformers.operators.linear.KTransformersLinear # optimized Kernel on quantized data types
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
prefill_device: "cuda"
|
||||
generate_op: "KLinearMarlin"
|
||||
prefill_op: "KLinearTorch"
|
||||
```
|
||||
|
||||
<h3 id="Pre-compute Buffers">Pre-compute Buffers </h3>
|
||||
|
||||
The original model is initialized on the meta device. The rotary embedding module pre-computes some buffers when initializing, which has no effect and doesn't compute anything when using the meta device. Therefore, we need to compute the buffers when loading the model. For convenience, we inject the rotary embedding module with our custom module, which performs pre-computations when loading. Here is the YAML rule:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
class: ktransformers.models.modeling_deepseek.DeepseekV2YarnRotaryEmbedding
|
||||
replace:
|
||||
class: ktransformers.operators.RoPE.YarnRotaryEmbedding
|
||||
```
|
||||
|
||||
## Wrap Your Custom Module
|
||||
|
||||
We have implemented some modules, but you may need to inject your custom module using KTransformers.
|
||||
The only thing you need to do is wrap your custom module and write YAML files. We provide a base operator specifying interfaces an injection module should have. You only need to inherit from that module and change the `__init__`, `forward`, or `load` function as needed.
|
||||
|
||||
- The `__init__` function of the base operator maintains the necessary information for injection and execution of the KTransformers framework. To override this function, subclass modules need to call the base operator's `__init__` function in their own initializer.
|
||||
- The `forward` function is a function in torch that will be called during inference, where the module author has the freedom to achieve higher performance.
|
||||
- The `load` function is used to load all parameters of this module. The default implementation is to call the `load` function of all submodules. You can modify this function to customize its loading method and explicitly control the loading of its submodules.
|
||||
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
# FP8 Linear Kernel for DeepSeek-V3/R1
|
||||
|
||||
## Overview
|
||||
The DeepSeek-AI team provides FP8 safetensors for DeepSeek-R1/V3 models. We achieve performance optimization through the following works:
|
||||
- **FP8 GPU Kernel Integration**: FP8 linear layer acceleration kernels integrated in KTransformers
|
||||
- **Hybrid Quantization Architecture**:
|
||||
- Attention and Shared-Expert modules use FP8 precision (enhances computational accuracy)
|
||||
- Experts modules retain GGML quantization (GGUF format, reside in CPU to save GPU memory)
|
||||
|
||||
So those who are persuing the best performance can use the FP8 linear kernel for DeepSeek-V3/R1.
|
||||
|
||||
## Key Features
|
||||
|
||||
✅ Hybrid Precision Architecture (FP8 + GGML)<br>
|
||||
✅ Memory Optimization (~19GB VRAM usage)
|
||||
|
||||
## Quick Start
|
||||
### Using Pre-Merged Weights
|
||||
|
||||
Pre-merged weights are available on Hugging Face:<br>
|
||||
[KVCache-ai/DeepSeek-V3-GGML-FP8-Hybrid](https://huggingface.co/KVCache-ai/DeepSeek-V3)<br>
|
||||
[KVCache-ai/DeepSeek-R1-GGML-FP8-Hybrid](https://huggingface.co/KVCache-ai/DeepSeek-R1)
|
||||
|
||||
> Please confirm the weights are fully uploaded before downloading. The large file size may extend Hugging Face upload time.
|
||||
|
||||
|
||||
Download Pre-Merged Weights
|
||||
```shell
|
||||
pip install -U huggingface_hub
|
||||
|
||||
# Optional: Use HF Mirror for faster downloads in special area.
|
||||
# export HF_ENDPOINT=https://hf-mirror.com
|
||||
|
||||
huggingface-cli download --resume-download KVCache-ai/DeepSeek-V3-GGML-FP8-Hybrid --local-dir <local_dir>
|
||||
```
|
||||
### Using merge scripts
|
||||
If you got local DeepSeek-R1/V3 fp8 safetensors and gguf weights(eg.q4km), you can merge them using the following scripts.
|
||||
|
||||
```shell
|
||||
python merge_tensors/merge_safetensor_gguf.py \
|
||||
--safetensor_path <fp8_safetensor_path> \
|
||||
--gguf_path <gguf_folder_path> \
|
||||
--output_path <merged_output_path>
|
||||
```
|
||||
|
||||
* `--safetensor_path`: input path of safetensor file([Download](https://huggingface.co/deepseek-ai/DeepSeek-V3/tree/main)).
|
||||
* `--gguf_path`: input path of gguf folder ([Download](https://huggingface.co/unsloth/DeepSeek-V3-GGUF/tree/main/DeepSeek-V3-Q4_K_M)).
|
||||
* `--output_path`: output path of merged file.
|
||||
|
||||
|
||||
### Execution Notes
|
||||
|
||||
Launch local_chat.py with custom quantized experts
|
||||
```shell
|
||||
python ktransformers/local_chat.py \
|
||||
--model_path deepseek-ai/DeepSeek-V3 \
|
||||
--gguf_path <merged_weights_folder> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-fp8-linear-ggml-experts.yaml \
|
||||
--cpu_infer <cpu_cores + 1>
|
||||
```
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
⚠️ Hardware Requirements<br>
|
||||
* Recommended minimum 19GB available VRAM for FP8 kernel.
|
||||
* Requires GPU with FP8 support (e.g., 4090)
|
||||
|
||||
⏳ First-Run Optimization
|
||||
JIT compilation causes longer initial execution (subsequent runs retain optimized speed).
|
||||
|
||||
🔄 Temporary Interface<br>
|
||||
Current weight loading implementation is provisional - will be refined in future versions
|
||||
|
||||
📁 Path Specification<br>
|
||||
Despite hybrid quantization, merged weights are stored as .safetensors - pass the containing folder path to `--gguf_path`
|
||||
|
|
@ -1,329 +0,0 @@
|
|||
# Tutorial: Inject Operator Step by Step
|
||||
|
||||
> Author: Azure-Tang
|
||||
|
||||
## TL;DR
|
||||
This tutorial will guide you through the process of injecting custom operators into a model using the KTransformers framework. We will use the DeepSeekV2-Chat model as an example to demonstrate how to inject custom operators into the model step by step. The tutorial will cover the following topics:
|
||||
* [How to write injection rules](#how-to-write-injection-rules)
|
||||
* [Understanding the structure of the model](#understanding-model-structure)
|
||||
* [Multi-GPU](#muti-gpu)
|
||||
* [How to write a new operator and inject it into the model](#how-to-write-a-new-operator-and-inject-into-the-model)
|
||||
|
||||
## How to Write Injection Rules
|
||||
The basic form of the injection rules for the Inject framework is as follows:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.*$" # Target module name
|
||||
class: torch.nn.Linear # Target module
|
||||
replace:
|
||||
class: "default"
|
||||
kwargs:
|
||||
generate_device: "cuda:0"
|
||||
# your_op_param_1: 1234
|
||||
# your_op_param_2: 5678
|
||||
recursive: True
|
||||
```
|
||||
* match: This field marks the matching rules, which can appear in two forms, name and class. These two matching rules can appear together or separately; they only match when both criteria are met.
|
||||
* replace:
|
||||
* class: Python class that can be imported to replace the target module. If no replacement is desired, set to default.
|
||||
* kwargs: List of parameters needed for module initialization.
|
||||
* generate_device: The device for this module, can be set to “cpu”, “cuda”, “cuda:1”, etc.
|
||||
* recursive: Whether to recursively inject this module’s submodules, default is True.
|
||||
|
||||
For the recursive field: Some modules contain multiple submodules, such as the Self-attention module typically includes q/k/v/o four linear modules. If we replace the self-attention module but do not want the internal linear modules to be covered by other rules, set this rule to False.
|
||||
|
||||
## Understanding Model Structure
|
||||
Using [deepseek-ai/DeepSeek-V2-Lite-Chat](https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite-Chat) as an example, we can follow the above rules step by step to inject our custom module and run it. KTransformers offers a high degree of flexibility, allowing you to replace/experiment with basic operators. However, it also requires users to clearly understand the structure of the model they are running.
|
||||
|
||||
Fortunately, knowing the structure of a model is very simple. Open the file list on the [deepseek-ai/DeepSeek-V2-Lite](https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite-Chat/tree/main) homepage, and you can see the following files:
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="../assets/model_structure_guild.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
From the `.saftensors` file, we can see the name of each layer’s weights, corresponding to the match.name attribute in the injection rules.
|
||||
From the `modeling_deepseek.py` file, we can see the specific implementation of each module class, with the class name corresponding to the match.class attribute in the injection rules.
|
||||
|
||||
The structure of the DeepSeekV2 model from the `.saftensors` and `modeling_deepseek.py` files is as follows:
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="../assets/deepseekv2_structure.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
Supported operators and their corresponding classes are as follows:
|
||||
|
||||
| match | replace | backends | descriptions |
|
||||
| --------- | ---------------------- | ----------------------- | -------------------- |
|
||||
| Linear | KTransformersLinear | KLinearMarlin | Marlin as backend |
|
||||
| | | KLinearTorch | pytorch as backend |
|
||||
| | | KLinearCPUInfer | llamafile as backend |
|
||||
| | | KLinearFP8 | Triton fp8_gemm kernel. Requires GPU be able to caluculate fp8 data |
|
||||
| experts | KTransformersExperts | KExpertsTorch | pytorch as backend |
|
||||
| | | KExpertsMarlin | Marlin as backend |
|
||||
| | | KExpertsCPU | llamafile as backend |
|
||||
| Attention | KDeepseekV2Attention | KDeepseekV2Attention | MLA implementation |
|
||||
| MoE | KMistralSparseMoEBlock | KQwen2MoeSparseMoeBlock | MoE for Qwen2 |
|
||||
| | KDeepseekV2MoE | KDeepseekV2MoE | MoE for DeepseekV2 |
|
||||
| Model | KQwen2MoeModel | KQwen2MoeModel | Model for Qwen2 |
|
||||
| | KDeepseekV2Model | KDeepseekV2Model | Model for DeepseekV2 |
|
||||
| RoPE | RotaryEmbedding | RotaryEmbedding | RoPE module |
|
||||
| | YarnRotaryEmbedding | YarnRotaryEmbedding | RoPE module |
|
||||
|
||||
Then we start step-by-step injection of custom modules, our targets are:
|
||||
|
||||
* Replace the linear module with custom Marlin linear module.
|
||||
* Replace the self-attention module with a custom Absorption-based MLA module.
|
||||
* Replace the experts module with a custom Experts module.
|
||||
* Replace the MoE module with a custom MoE module.
|
||||
* Replace the RoPE module with a custom RoPE module.
|
||||
* Set the running device for each module.
|
||||
|
||||
The full implementation of the injection rules can be found in the [here](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V2-Chat.yaml).
|
||||
|
||||
## Matrix Absorption-based MLA Injection
|
||||
|
||||
For the injection of the Attention module, we only need to use a regular expression to match the module names used in transformers and replace them with our own MLA module implementation. The YAML injection rule is as follows:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.self_attn$" # Regular expression
|
||||
replace:
|
||||
class: ktransformers.operators.attention.KDeepseekV2Attention # Optimized MLA implementation
|
||||
```
|
||||
As you can see, each rule in the YAML file has two parts: match and replace. The match part specifies the module to be replaced, and the replace part specifies the module to be injected into the model along with the initialization keywords.
|
||||
|
||||
## Injection of Routed Experts
|
||||
For Routed Experts (corresponding to the exps in the diagram), the module we inject is CPUInfer, which is wrapped in the wrapper module KTransformersExperts. KTransformersExperts has multiple implementations, and we need to specify keywords to tell the wrapper module which implementation we want to use and how we plan to use it.
|
||||
|
||||
In the source code of the transformer, MoE is implemented using nn.ModuleList. We do not want KTransformers to traverse all submodules in the list and inject them one by one, so in this rule, we set recursive: False to prevent recursive injection into the submodules of this module. The YAML rule is as follows:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # Custom MoE kernel with expert parallelism
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "MLPCPUExperts"
|
||||
out_device: "cuda"
|
||||
recursive: False # Don't recursively inject submodules of this module
|
||||
```
|
||||
|
||||
If we inject Routed Experts as a custom module, we cannot use the interfaces in the original `nn.ModuleList`. Therefore, it is necessary to modify the forward function in the FFN module. The simplest method is to implement a new module with a custom forward function and inject it.
|
||||
```yaml
|
||||
- match:
|
||||
class: ktransformers.models.modeling_deepseek.DeepseekV2MoE
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KDeepseekV2MoE # MLP module with custom forward function
|
||||
```
|
||||
|
||||
## Injection of Linear Layers
|
||||
|
||||
For the remaining linear layer modules, we aim to use quantized operators to save storage space while improving performance. Since there is no current research on using MLA and quantization together, we do not want to inject linear into the MLA operator. Therefore, we can modify the regular expression and add a type check in the match part of the rule. Only modules that match both the name and class simultaneously will be injected. We also need to pass some keywords similar to the injection of Routed Experts. The YAML rule is as follows:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\.(?!.*self_attn).*$" # Regular expression
|
||||
class: torch.nn.Linear # Only match modules matching name and class simultaneously
|
||||
replace:
|
||||
class: ktransformers.operators.linear.KTransformersLinear # Optimized kernel on quantized data types
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
generate_op: "QuantizedLinearMarlin"
|
||||
```
|
||||
## Injection of Modules with Pre-calculated Buffers
|
||||
|
||||
To avoid occupying resources when initializing the injected original model, we use torch’s meta device to initialize the original model. The RoPE module pre-calculates some buffers during initialization, but no calculations are performed when using the meta device. Therefore, we need to compensate for the calculation of the buffer when loading the model. Simply, we inject a custom module into the rotary embedding module, which performs pre-calculation during loading. The YAML rule is as follows:
|
||||
```yaml
|
||||
- match:
|
||||
class: ktransformers.models.modeling_deepseek.DeepseekV2YarnRotaryEmbedding
|
||||
replace:
|
||||
class: ktransformers.operators.RoPE.YarnRotaryEmbedding
|
||||
```
|
||||
|
||||
## Specifying Running Devices for Modules
|
||||
|
||||
Finally, we set a fallback basic attribute generate_device for all modules:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.|^lm_head"
|
||||
replace:
|
||||
class: "default"
|
||||
kwargs:
|
||||
generate_device: "cuda"
|
||||
|
||||
- match:
|
||||
name: "^model.embed_tokens"
|
||||
replace:
|
||||
class: "default"
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
```
|
||||
Through these two rules, we place all previously unmatched layers (and their submodules) and lm_head on cuda, and the embedding on cpu. Note that the properties of a module will be determined by the first rule it matches. For example, if you later set a new replace.kwargs.generate_device in an injected module, the device set earlier will take precedence. If your computer has multiple cards, you can also configure the model to multiple cards.
|
||||
|
||||
|
||||
## Muti-GPU
|
||||
|
||||
If you have multiple GPUs, you can set the device for each module to different GPUs.
|
||||
DeepseekV2-Chat got 60 layers, if we got 2 GPUs, we can allocate 30 layers to each GPU. Complete multi GPU rule examples [here](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V2-Chat-multi-gpu.yaml).
|
||||
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="../assets/multi_gpu.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
First of all, for multi-GPU, we have to inject an new operator `KDeepseekV2Model`. And set division of the layers to different GPUs. For our case, we have to set the `transfer_map` in the `KDeepseekV2Model` operatoras as follows:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model$"
|
||||
replace:
|
||||
class: "ktransformers.operators.models.KDeepseekV2Model"
|
||||
kwargs:
|
||||
transfer_map:
|
||||
30: "cuda:1"
|
||||
```
|
||||
|
||||
And we have to set the device for each module in the model.
|
||||
|
||||
For example, for `routed experts`, the yaml for one GPU is:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # Custom MoE kernel with expert parallelism
|
||||
kwargs:
|
||||
generate_device: "cuda:0"
|
||||
generate_op: "MLPCUDAExperts"
|
||||
out_device: "cuda:0"
|
||||
recursive: False # Don't recursively inject submodules of this module
|
||||
```
|
||||
But for two GPUs, we need to set the device for each module in the model.
|
||||
|
||||
```yaml
|
||||
# allcate 0-29 layers‘s out_device to cuda:0
|
||||
- match:
|
||||
name: "^model\\.layers\\.(0|[1-9]|[12][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert paralleism
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:0"
|
||||
recursive: False # don't recursively inject submodules of this module
|
||||
|
||||
# allocate 30-59 layers‘s out_device to cuda:1
|
||||
- match:
|
||||
name: "^model\\.layers\\.([345][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert paralleism
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:1"
|
||||
recursive: False # don't recursively inject submodules of this module
|
||||
```
|
||||
For other modules, we can set the device in the same way.
|
||||
|
||||
## How to Write a New Operator and Inject into the Model
|
||||
|
||||
In this section, we will explain how to write an operator that can be injected, using the implementation of a new linear as an example.
|
||||
|
||||
First, all injectable operators need to inherit from the BaseInjectedModule class, which inherits some attributes required by our injection framework. Its initialization function needs to meet the following basic format:
|
||||
|
||||
```python
|
||||
class LinearTorchInject(BaseInjectedModule):
|
||||
def __init__(
|
||||
self,
|
||||
key: str,
|
||||
gguf_loader: GGUFLoader,
|
||||
config: PretrainedConfig,
|
||||
orig_module: nn.Module = None,
|
||||
generate_device: str = "cuda",
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(key, gguf_loader, config, orig_module, generate_device, **kwargs)
|
||||
```
|
||||
If users have other parameters that need to be passed to this class, they can also be included in the init function and re-passed in the kwargs parameter in the yaml file. For example, if our operator wants to pass a parameter `my_param`, the init function can be written as:
|
||||
```python
|
||||
class LinearTorchInject(BaseInjectedModule):
|
||||
def __init__(
|
||||
self,
|
||||
key: str,
|
||||
gguf_loader: GGUFLoader,
|
||||
config: PretrainedConfig,
|
||||
orig_module: nn.Module = None,
|
||||
generate_device: str = "cuda",
|
||||
my_param: bool = True,
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(key, gguf_loader, config, orig_module, generate_device, **kwargs)
|
||||
self.my_param = my_param
|
||||
```
|
||||
Then our injection rule can be written as:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*$" # Regular expression matches the module name.
|
||||
class: torch.nn.Linear # Type restrictions can be added.
|
||||
replace:
|
||||
class: ktransformers.operators.linear.LinearTorchInject # Inject module path
|
||||
kwargs: # Extra parameters
|
||||
generate_device: "cuda"
|
||||
my_param: True
|
||||
```
|
||||
For the linear module, it is also necessary to read weights from a gguf file. We provide the `KLinearBase` class to help users read weights from gguf files. Users only need to inherit and implement the load, unload, and forward functions. Therefore, a fully injectable linear class would look like this:
|
||||
```python
|
||||
class LinearTorchInject(BaseInjectedModule, KLinearBase):
|
||||
def __init__(
|
||||
self,
|
||||
key: str,
|
||||
gguf_loader: GGUFLoader,
|
||||
config: PretrainedConfig,
|
||||
orig_module: nn.Module = None,
|
||||
generate_device: str = "cuda",
|
||||
**kwargs,
|
||||
):
|
||||
super().__init__(key, gguf_loader, config, orig_module, generate_device, **kwargs)
|
||||
KLinearBase.__init__(self)
|
||||
self.has_bias = False
|
||||
self.dtype = torch.get_default_dtype()
|
||||
self.w = None
|
||||
self.has_bias = False
|
||||
|
||||
def load(self, w: dict | nn.Parameter | tuple | None = None, device: str|None = None):
|
||||
if device is None: device = self.device
|
||||
if w is None: w = self.load_weight(device=device)
|
||||
|
||||
if isinstance(w, nn.Parameter):
|
||||
self.w = w.to(dtype=self.dtype).view(self.out_features, self.in_features).T
|
||||
self.has_bias = False
|
||||
elif isinstance(w, tuple):
|
||||
self.w = w[0].to(dtype=self.dtype).view(self.out_features, self.in_features).T
|
||||
self.bias = w[1].to(dtype=self.dtype)
|
||||
self.has_bias = True
|
||||
else:
|
||||
raise ValueError("Invalid weight type")
|
||||
self.w = self.w.to(device)
|
||||
if self.has_bias:
|
||||
self.bias = self.bias.to(device)
|
||||
|
||||
def unload(self):
|
||||
if self.w is not None:
|
||||
self.w = None
|
||||
if self.has_bias:
|
||||
self.bias = None
|
||||
|
||||
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
||||
dtype = x.dtype
|
||||
out_device = x.device
|
||||
x = x.to(device=self.device, dtype=self.dtype)
|
||||
x = x @ self.w
|
||||
if self.has_bias:
|
||||
x = x + self.bias
|
||||
x = x.to(dtype=dtype, device=out_device)
|
||||
return x
|
||||
```
|
||||
Note that the `self.load_weight` function is provided by the KLinearBase class to help users load weights from a gguf file into the module. The implementation details of KLinearBase can be found on [GITHUB](https://github.com/kvcache-ai/ktransformers/blob/44f57270c9514d79fab224186d90ccf61059331a/ktransformers/operators/linear.py#L31).
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
<!-- omit in toc -->
|
||||
|
||||
# How to Run DeepSeek-R1
|
||||
|
||||
- [How to Run DeepSeek-R1](#how-to-run-deepseek-r1)
|
||||
- [Preparation](#preparation)
|
||||
- [Installation](#installation)
|
||||
- [Attention](#attention)
|
||||
- [Supported models include](#supported-models-include)
|
||||
- [Support quantize format](#support-quantize-format)
|
||||
|
||||
In this document, we will show you how to install and run KTransformers on your local machine. There are two versions:
|
||||
|
||||
* V0.2 is the current main branch.
|
||||
* V0.3 is a preview version only provides binary distribution for now.
|
||||
* To reproduce our DeepSeek-R1/V3 results, please refer to [Deepseek-R1/V3 Tutorial](./DeepseekR1_V3_tutorial.md) for more detail settings after installation.
|
||||
|
||||
## Preparation
|
||||
|
||||
Some preparation:
|
||||
|
||||
- CUDA 12.1 and above, if you didn't have it yet, you may install from [here](https://developer.nvidia.com/cuda-downloads).
|
||||
|
||||
```sh
|
||||
# Adding CUDA to PATH
|
||||
if [ -d "/usr/local/cuda/bin" ]; then
|
||||
export PATH=$PATH:/usr/local/cuda/bin
|
||||
fi
|
||||
|
||||
if [ -d "/usr/local/cuda/lib64" ]; then
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64
|
||||
# Or you can add it to /etc/ld.so.conf and run ldconfig as root:
|
||||
# echo "/usr/local/cuda-12.x/lib64" | sudo tee -a /etc/ld.so.conf
|
||||
# sudo ldconfig
|
||||
fi
|
||||
|
||||
if [ -d "/usr/local/cuda" ]; then
|
||||
export CUDA_PATH=$CUDA_PATH:/usr/local/cuda
|
||||
fi
|
||||
```
|
||||
- Linux-x86_64 with gcc, g++>=11 and cmake>=3.25 (using Ubuntu as an example)
|
||||
- **Note**: The default CMake version in Ubuntu 22.04 LTS or higher may not support newer CUDA language dialects (e.g., CUDA 20). This can cause errors such as Target "cmTC_xxxxxx" requires the language dialect "CUDA20", but CMake does not know the compile flags to use to enable it. To resolve this, install a newer CMake version, for instance, by adding the Kitware APT repository.
|
||||
|
||||
```sh
|
||||
sudo apt-get update
|
||||
sudo apt-get install build-essential cmake ninja-build patchelf
|
||||
```
|
||||
- We recommend using [Miniconda3](https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh) or [Anaconda3](https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh) to create a virtual environment with Python=3.11 to run our program. Assuming your Anaconda installation directory is `~/anaconda3`, you should ensure that the version identifier of the GNU C++standard library used by Anaconda includes `GLIBCXX_3.4.32`
|
||||
|
||||
```sh
|
||||
conda create --name ktransformers python=3.11
|
||||
conda activate ktransformers # you may need to run ‘conda init’ and reopen shell first
|
||||
|
||||
conda install -c conda-forge libstdcxx-ng # Anaconda provides a package called `libstdcxx-ng` that includes a newer version of `libstdc++`, which can be installed via `conda-forge`.
|
||||
|
||||
strings ~/anaconda3/envs/ktransformers/lib/libstdc++.so.6 | grep GLIBCXX
|
||||
```
|
||||
- Make sure that PyTorch, packaging, ninja is installed You can also [install previous versions of PyTorch](https://pytorch.org/get-started/previous-versions/)
|
||||
|
||||
```
|
||||
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
|
||||
pip3 install packaging ninja cpufeature numpy
|
||||
```
|
||||
- At the same time, you should download and install the corresponding version of flash-attention from https://github.com/Dao-AILab/flash-attention/releases.
|
||||
|
||||
## Installation
|
||||
|
||||
### Attention
|
||||
|
||||
If you want to use numa support, not only do you need to set USE_NUMA=1, but you also need to make sure you have installed the libnuma-dev (`sudo apt-get install libnuma-dev` may help you).
|
||||
|
||||
[Optional] If you want to use the multi-concurrent version, please install the following dependencies.
|
||||
|
||||
```
|
||||
sudo apt install libtbb-dev libssl-dev libcurl4-openssl-dev libaio1 libaio-dev libgflags-dev zlib1g-dev libfmt-dev
|
||||
```
|
||||
|
||||
<!-- 1. ~~Use a Docker image, see [documentation for Docker](./doc/en/Docker.md)~~
|
||||
|
||||
>We are working on the latest docker image, please wait for a while.
|
||||
|
||||
2. ~~You can install using Pypi (for linux):~~
|
||||
> We are working on the latest pypi package, please wait for a while.
|
||||
|
||||
```
|
||||
pip install ktransformers --no-build-isolation
|
||||
```
|
||||
|
||||
for windows we prepare a pre compiled whl package on [ktransformers-0.2.0+cu125torch24avx2-cp312-cp312-win_amd64.whl](https://github.com/kvcache-ai/ktransformers/releases/download/v0.2.0/ktransformers-0.2.0+cu125torch24avx2-cp312-cp312-win_amd64.whl), which require cuda-12.5, torch-2.4, python-3.11, more pre compiled package are being produced. -->
|
||||
|
||||
Download source code and compile:
|
||||
|
||||
- init source code
|
||||
|
||||
```sh
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
- [Optional] If you want to run with website, please [compile the website](./api/server/website.md) before execute ``bash install.sh``
|
||||
- For Linux
|
||||
|
||||
- For simple install:
|
||||
|
||||
```shell
|
||||
bash install.sh
|
||||
```
|
||||
- For those who have two cpu and 1T RAM:
|
||||
|
||||
```shell
|
||||
# Make sure your system has dual sockets and double size RAM than the model's size (e.g. 1T RAM for 512G model)
|
||||
apt install libnuma-dev
|
||||
export USE_NUMA=1
|
||||
bash install.sh # or #make dev_install
|
||||
```
|
||||
- For Multi-concurrency with 500G RAM:
|
||||
|
||||
```shell
|
||||
USE_BALANCE_SERVE=1 bash ./install.sh
|
||||
```
|
||||
- For Multi-concurrency with two cpu and 1T RAM:
|
||||
|
||||
```shell
|
||||
USE_BALANCE_SERVE=1 USE_NUMA=1 bash ./install.sh
|
||||
```
|
||||
- For Windows (Windows native temporarily deprecated, please try WSL)
|
||||
|
||||
```shell
|
||||
install.bat
|
||||
```
|
||||
|
||||
* If you are developer, you can make use of the makefile to compile and format the code. <br> the detailed usage of makefile is [here](./makefile_usage.md)
|
||||
|
||||
<h3>Local Chat</h3>
|
||||
We provide a simple command-line local chat Python script that you can run for testing.
|
||||
|
||||
> Note: this is a very simple test tool only support one round chat without any memory about last input, if you want to try full ability of the model, you may go to [RESTful API and Web UI](#id_666).
|
||||
|
||||
<h4>Run Example</h4>
|
||||
|
||||
```shell
|
||||
# Begin from root of your cloned repo!
|
||||
# Begin from root of your cloned repo!!
|
||||
# Begin from root of your cloned repo!!!
|
||||
|
||||
# Download mzwing/DeepSeek-V2-Lite-Chat-GGUF from huggingface
|
||||
mkdir DeepSeek-V2-Lite-Chat-GGUF
|
||||
cd DeepSeek-V2-Lite-Chat-GGUF
|
||||
|
||||
wget https://huggingface.co/mradermacher/DeepSeek-V2-Lite-GGUF/resolve/main/DeepSeek-V2-Lite.Q4_K_M.gguf -O DeepSeek-V2-Lite-Chat.Q4_K_M.gguf
|
||||
|
||||
cd .. # Move to repo's root dir
|
||||
|
||||
# Start local chat
|
||||
python -m ktransformers.local_chat --model_path deepseek-ai/DeepSeek-V2-Lite-Chat --gguf_path ./DeepSeek-V2-Lite-Chat-GGUF
|
||||
|
||||
# If you see “OSError: We couldn't connect to 'https://huggingface.co' to load this file”, try:
|
||||
# GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite
|
||||
# python ktransformers.local_chat --model_path ./DeepSeek-V2-Lite --gguf_path ./DeepSeek-V2-Lite-Chat-GGUF
|
||||
```
|
||||
|
||||
It features the following arguments:
|
||||
|
||||
- `--model_path` (required): Name of the model (such as "deepseek-ai/DeepSeek-V2-Lite-Chat" which will automatically download configs from [Hugging Face](https://huggingface.co/deepseek-ai/DeepSeek-V2-Lite)). Or if you already got local files you may directly use that path to initialize the model.
|
||||
|
||||
> Note: <strong>.safetensors</strong> files are not required in the directory. We only need config files to build model and tokenizer.
|
||||
>
|
||||
- `--gguf_path` (required): Path of a directory containing GGUF files which could that can be downloaded from [Hugging Face](https://huggingface.co/mzwing/DeepSeek-V2-Lite-Chat-GGUF/tree/main). Note that the directory should only contains GGUF of current model, which means you need one separate directory for each model.
|
||||
- `--optimize_config_path` (required except for Qwen2Moe and DeepSeek-V2): Path of YAML file containing optimize rules. There are two rule files pre-written in the [ktransformers/optimize/optimize_rules](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/optimize/optimize_rules) directory for optimizing DeepSeek-V2 and Qwen2-57B-A14, two SOTA MoE models.
|
||||
- `--max_new_tokens`: Int (default=1000). Maximum number of new tokens to generate.
|
||||
- `--cpu_infer`: Int (default=10). The number of CPUs used for inference. Should ideally be set to the (total number of cores - 2).
|
||||
|
||||
<h3>Start Server</h3>
|
||||
We provide a server script, which supports multi-concurrency functionality in version v0.2.4.
|
||||
|
||||
```
|
||||
python ktransformers/server/main.py --model_path /mnt/data/models/DeepSeek-V3 --gguf_path /mnt/data/models/DeepSeek-V3-GGUF/DeepSeek-V3-Q4_K_M/ --cpu_infer 62 --optimize_config_path ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-serve.yaml --port 10002 --chunk_size 256 --max_new_tokens 1024 --max_batch_size 4 --port 10002 --cache_lens 32768 --backend_type balance_serve
|
||||
```
|
||||
|
||||
It features the following arguments:
|
||||
|
||||
- `--chunk_size`: Maximum number of tokens processed in a single run by the engine.
|
||||
- `--cache_lens`: Total length of kvcache allocated by the scheduler. All requests share a kvcache space corresponding to 32768 tokens, and the space occupied will be released after the requests are completed.
|
||||
- `--backend_type`: `balance_serve` is a multi-concurrency backend engine introduced in version v0.2.4. The original single-concurrency engine is `ktransformers`.
|
||||
- `--max_batch_size`: Maximum number of requests (prefill + decode) processed in a single run by the engine. (Supported only by `balance_serve`)
|
||||
|
||||
<details>
|
||||
<summary>Supported Models/quantization</summary>
|
||||
|
||||
### Supported models include
|
||||
|
||||
|
||||
| ✅**Supported Models** | ❌**Deprecated Models** |
|
||||
| ---------------------- | -------------------------- |
|
||||
| DeepSeek-R1 | ~~InternLM2.5-7B-Chat-1M~~ |
|
||||
| DeepSeek-V3 | |
|
||||
| DeepSeek-V2 | |
|
||||
| DeepSeek-V2.5 | |
|
||||
| Qwen2-57B | |
|
||||
| DeepSeek-V2-Lite | |
|
||||
| Mixtral-8x7B | |
|
||||
| Mixtral-8x22B | |
|
||||
|
||||
### Support quantize format
|
||||
|
||||
|
||||
| ✅**Supported Formats** | ❌**Deprecated Formats** |
|
||||
| ----------------------- | ------------------------ |
|
||||
| IQ1_S | ~~IQ2_XXS~~ |
|
||||
| IQ2_XXS | |
|
||||
| Q2_K_L | |
|
||||
| Q2_K_XS | |
|
||||
| Q3_K_M | |
|
||||
| Q4_K_M | |
|
||||
| Q5_K_M | |
|
||||
| Q6_K | |
|
||||
| Q8_0 | |
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Suggested Model</summary>
|
||||
|
||||
|
||||
| Model Name | Model Size | VRAM | Minimum DRAM | Recommended DRAM |
|
||||
| ------------------------------ | ---------- | ----- | --------------- | ----------------- |
|
||||
| DeepSeek-R1-q4_k_m | 377G | 14G | 382G | 512G |
|
||||
| DeepSeek-V3-q4_k_m | 377G | 14G | 382G | 512G |
|
||||
| DeepSeek-V2-q4_k_m | 133G | 11G | 136G | 192G |
|
||||
| DeepSeek-V2.5-q4_k_m | 133G | 11G | 136G | 192G |
|
||||
| DeepSeek-V2.5-IQ4_XS | 117G | 10G | 107G | 128G |
|
||||
| Qwen2-57B-A14B-Instruct-q4_k_m | 33G | 8G | 34G | 64G |
|
||||
| DeepSeek-V2-Lite-q4_k_m | 9.7G | 3G | 13G | 16G |
|
||||
| Mixtral-8x7B-q4_k_m | 25G | 1.6G | 51G | 64G |
|
||||
| Mixtral-8x22B-q4_k_m | 80G | 4G | 86.1G | 96G |
|
||||
| InternLM2.5-7B-Chat-1M | 15.5G | 15.5G | 8G(32K context) | 150G (1M context) |
|
||||
|
||||
More will come soon. Please let us know which models you are most interested in.
|
||||
|
||||
Be aware that you need to be subject to their corresponding model licenses when using [DeepSeek](https://huggingface.co/deepseek-ai/DeepSeek-V2/blob/main/LICENSE) and [QWen](https://huggingface.co/Qwen/Qwen2-72B-Instruct/blob/main/LICENSE).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Click To Show how to run other examples</summary>
|
||||
|
||||
* Qwen2-57B
|
||||
|
||||
```sh
|
||||
pip install flash_attn # For Qwen2
|
||||
|
||||
mkdir Qwen2-57B-GGUF && cd Qwen2-57B-GGUF
|
||||
|
||||
wget https://huggingface.co/Qwen/Qwen2-57B-A14B-Instruct-GGUF/resolve/main/qwen2-57b-a14b-instruct-q4_k_m.gguf?download=true -O qwen2-57b-a14b-instruct-q4_k_m.gguf
|
||||
|
||||
cd ..
|
||||
|
||||
python -m ktransformers.local_chat --model_name Qwen/Qwen2-57B-A14B-Instruct --gguf_path ./Qwen2-57B-GGUF
|
||||
|
||||
# If you see “OSError: We couldn't connect to 'https://huggingface.co' to load this file”, try:
|
||||
# GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/Qwen/Qwen2-57B-A14B-Instruct
|
||||
# python ktransformers/local_chat.py --model_path ./Qwen2-57B-A14B-Instruct --gguf_path ./DeepSeek-V2-Lite-Chat-GGUF
|
||||
```
|
||||
* Deepseek-V2
|
||||
|
||||
```sh
|
||||
mkdir DeepSeek-V2-Chat-0628-GGUF && cd DeepSeek-V2-Chat-0628-GGUF
|
||||
# Download weights
|
||||
wget https://huggingface.co/bartowski/DeepSeek-V2-Chat-0628-GGUF/resolve/main/DeepSeek-V2-Chat-0628-Q4_K_M/DeepSeek-V2-Chat-0628-Q4_K_M-00001-of-00004.gguf -o DeepSeek-V2-Chat-0628-Q4_K_M-00001-of-00004.gguf
|
||||
wget https://huggingface.co/bartowski/DeepSeek-V2-Chat-0628-GGUF/resolve/main/DeepSeek-V2-Chat-0628-Q4_K_M/DeepSeek-V2-Chat-0628-Q4_K_M-00002-of-00004.gguf -o DeepSeek-V2-Chat-0628-Q4_K_M-00002-of-00004.gguf
|
||||
wget https://huggingface.co/bartowski/DeepSeek-V2-Chat-0628-GGUF/resolve/main/DeepSeek-V2-Chat-0628-Q4_K_M/DeepSeek-V2-Chat-0628-Q4_K_M-00003-of-00004.gguf -o DeepSeek-V2-Chat-0628-Q4_K_M-00003-of-00004.gguf
|
||||
wget https://huggingface.co/bartowski/DeepSeek-V2-Chat-0628-GGUF/resolve/main/DeepSeek-V2-Chat-0628-Q4_K_M/DeepSeek-V2-Chat-0628-Q4_K_M-00004-of-00004.gguf -o DeepSeek-V2-Chat-0628-Q4_K_M-00004-of-00004.gguf
|
||||
|
||||
cd ..
|
||||
|
||||
python -m ktransformers.local_chat --model_name deepseek-ai/DeepSeek-V2-Chat-0628 --gguf_path ./DeepSeek-V2-Chat-0628-GGUF
|
||||
|
||||
# If you see “OSError: We couldn't connect to 'https://huggingface.co' to load this file”, try:
|
||||
|
||||
# GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/deepseek-ai/DeepSeek-V2-Chat-0628
|
||||
|
||||
# python -m ktransformers.local_chat --model_path ./DeepSeek-V2-Chat-0628 --gguf_path ./DeepSeek-V2-Chat-0628-GGUF
|
||||
```
|
||||
|
||||
|
||||
| model name | weights download link |
|
||||
| ---------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| Qwen2-57B | [Qwen2-57B-A14B-gguf-Q4K-M](https://huggingface.co/Qwen/Qwen2-57B-A14B-Instruct-GGUF/tree/main) |
|
||||
| DeepseekV2-coder | [DeepSeek-Coder-V2-Instruct-gguf-Q4K-M](https://huggingface.co/LoneStriker/DeepSeek-Coder-V2-Instruct-GGUF/tree/main) |
|
||||
| DeepseekV2-chat | [DeepSeek-V2-Chat-gguf-Q4K-M](https://huggingface.co/bullerwins/DeepSeek-V2-Chat-0628-GGUF/tree/main) |
|
||||
| DeepseekV2-lite | [DeepSeek-V2-Lite-Chat-GGUF-Q4K-M](https://huggingface.co/mzwing/DeepSeek-V2-Lite-Chat-GGUF/tree/main) |
|
||||
| DeepSeek-R1 | [DeepSeek-R1-gguf-Q4K-M](https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-Q4_K_M) |
|
||||
|
||||
</details>
|
||||
|
||||
<!-- pin block for jump -->
|
||||
|
||||
<span id='id_666'>
|
||||
|
||||
<h3>RESTful API and Web UI </h3>
|
||||
|
||||
Start without website:
|
||||
|
||||
```sh
|
||||
ktransformers --model_path deepseek-ai/DeepSeek-V2-Lite-Chat --gguf_path /path/to/DeepSeek-V2-Lite-Chat-GGUF --port 10002
|
||||
```
|
||||
|
||||
Start with website:
|
||||
|
||||
```sh
|
||||
ktransformers --model_path deepseek-ai/DeepSeek-V2-Lite-Chat --gguf_path /path/to/DeepSeek-V2-Lite-Chat-GGUF --port 10002 --web True
|
||||
```
|
||||
|
||||
Or you want to start server with transformers, the model_path should include safetensors
|
||||
|
||||
```bash
|
||||
ktransformers --type transformers --model_path /mnt/data/model/Qwen2-0.5B-Instruct --port 10002 --web True
|
||||
```
|
||||
|
||||
Access website with url [http://localhost:10002/web/index.html#/chat](http://localhost:10002/web/index.html#/chat) :
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Web UI" src="https://github.com/user-attachments/assets/615dca9b-a08c-4183-bbd3-ad1362680faf" width=90%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
More information about the RESTful API server can be found [here](doc/en/api/server/server.md). You can also find an example of integrating with Tabby [here](doc/en/api/server/tabby.md).
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
# 🦙 Tutorial: LLaMA 4 Multi-Concurrency Support with KTransformers (Balance Serve Backend)
|
||||
|
||||
## 📌 Overview
|
||||
|
||||
We are pleased to announce that **KTransformers** now provides **experimental support for LLaMA 4 models** through the powerful `balance_serve` backend introduced in **v0.2.4**. This update is available under the dedicated development branch: [`support-llama4`](https://github.com/kvcache-ai/ktransformers/tree/support-llama4), specifically targeting the newly released **Meta LLaMA 4** model architecture.
|
||||
|
||||
⚠️ This support is currently **not available on the main branch** due to dependencies on newer versions of `transformers`, and **compatibility limitations with inference of currently supported models**. Work is underway to integrate this into the mainline once broader stability and compatibility are validated.
|
||||
|
||||
💡 **If you already have an environment based on the main branch**, it is **strongly recommended to create a new environment** to avoid potential dependency conflicts.
|
||||
|
||||
------
|
||||
|
||||
## 🔗 Model & Resource Links
|
||||
|
||||
- 🔥 Official LLaMA 4 Release: https://huggingface.co/meta-llama/Llama-4-Scout-17B-16E-Instruct
|
||||
(Note: LLaMA 4 models are served through the Meta repository. Make sure to **agree to terms** before downloading.)
|
||||
- 🧠 GGUF Format (quantized models):
|
||||
- https://huggingface.co/unsloth/Llama-4-Scout-17B-16E-Instruct-GGUF
|
||||
|
||||
------
|
||||
|
||||
## 🧪 Demo
|
||||
|
||||
https://github.com/user-attachments/assets/449706f1-784b-4931-b2ba-07687c1aca54
|
||||
|
||||
------
|
||||
|
||||
## Resource Requirements
|
||||
|
||||
The Scout model running with 16 Experts requires approximately 65 GB of memory and 10 GB of GPU memory, while the Maverick model with 128 Experts requires approximately 270 GB of memory and 12 GB of GPU memory.
|
||||
|
||||
------
|
||||
|
||||
## ⚙️ Usage Instructions
|
||||
|
||||
### 1. Clone `support-llama4` Branch
|
||||
|
||||
```bash
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git checkout support-llama4
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
### 2. Set Up Environment
|
||||
|
||||
```bash
|
||||
# Download Miniconda
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
|
||||
# Create environment
|
||||
conda create --name ktransformers python=3.11
|
||||
conda activate ktransformers
|
||||
|
||||
# Install required libraries
|
||||
conda install -c conda-forge libstdcxx-ng
|
||||
|
||||
# Verify GLIBCXX version (should include 3.4.32)
|
||||
strings ~/anaconda3/envs/ktransformers/lib/libstdc++.so.6 | grep GLIBCXX
|
||||
|
||||
sudo apt install libtbb-dev libssl-dev libcurl4-openssl-dev libaio1 libaio-dev libfmt-dev libgflags-dev zlib1g-dev patchelf
|
||||
pip3 install packaging ninja cpufeature numpy openai
|
||||
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126
|
||||
```
|
||||
|
||||
### 3. Build with Balance Serve Support
|
||||
|
||||
```bash
|
||||
# Install single NUMA dependencies
|
||||
USE_BALANCE_SERVE=1 bash ./install.sh
|
||||
# For those who have two cpu and 1T RAM(Dual NUMA):
|
||||
USE_BALANCE_SERVE=1 USE_NUMA=1 bash ./install.sh
|
||||
```
|
||||
|
||||
### 4. Use our custom config.json
|
||||
|
||||
Currently, you need to copy the content of our custom config file into the `config.json` under your `--model_path`.
|
||||
- Use [scout_config.json](https://github.com/kvcache-ai/ktransformers/blob/support-llama4/doc/en/scout_config.json) for the Llama-4-Scout-17B-16E model
|
||||
- Use [maverick_config.json](https://github.com/kvcache-ai/ktransformers/blob/support-llama4/doc/en/maverick_config.json) for the Llama-4-Maverick-17B-128E model
|
||||
|
||||
Please make sure to replace the content of `config.json` with the appropriate one accordingly.
|
||||
|
||||
### 5. Run LLaMA 4 Inference Server
|
||||
|
||||
Make sure you have:
|
||||
|
||||
- `--model_path` pointing to a local config directory (not a Hugging Face name).
|
||||
- `--gguf_path` pointing to the folder containing quantized `.gguf` weights.
|
||||
|
||||
```bash
|
||||
python ktransformers/server/main.py \
|
||||
--port 10002 \
|
||||
--model_path <path_to_safetensor_config> \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/Llama4-serve.yaml \
|
||||
--max_new_tokens 1024 \
|
||||
--cache_lens 32768 \
|
||||
--chunk_size 256 \
|
||||
--max_batch_size 4 \
|
||||
--backend_type balance_serve \
|
||||
```
|
||||
|
||||
### 5. Access server
|
||||
|
||||
```
|
||||
curl -X POST http://localhost:10002/v1/chat/completions \
|
||||
-H "accept: application/json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"messages": [
|
||||
{"role": "user", "content": "hello"}
|
||||
],
|
||||
"model": "Llama4",
|
||||
"temperature": 0.3,
|
||||
"top_p": 1.0,
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
------
|
||||
|
||||
## 📌 Limitations
|
||||
|
||||
- ✅ **Only `balance_serve` backend is supported** for LLaMA 4 models in this version.
|
||||
- ⚠️ Requires **`transformers==4.51.0`** or newer. Due to potential compatibility issues with older toolchains, we have **not merged this branch to main yet**.
|
||||
- ❌ Multimodal models are not supported yet in this version. Support will be added in future releases.
|
||||
|
|
@ -1,316 +0,0 @@
|
|||
# KVCache Long Context
|
||||
|
||||
## TL;DR
|
||||
|
||||
Training larger models and supporting longer text sequences are currently the two most widely agreed-upon directions toward achieving AGI. After lowering the barrier for local inference with trillion-parameter MoE models, the second showcase scenario for KTransformers is reducing the inference barrier for ultra-long context sequences. Recently, both ChatGLM and InternLM have released open-source models supporting 1M tokens of context. This article will use InternLM2.5-7B-Chat-1M as an example to introduce a method that leverages the sparsity of attention to accelerate long-text inference on heterogeneous CPU/GPU systems.
|
||||
|
||||
After optimization, KTransformers has achieved native-precision inference for 128K and even 1M tokens of context on a single 24GB GPU with CPU/DRAM support. In the 128K context scenario, the generation speed is 7.1 times faster than llama.cpp, while also achieving 100% accuracy on relatively simple test sets like "needle in haystack" and "passkey". On the more challenging dataset kvretrieval, through flexible framework configurations, we can achieve a **6.22x speedup** during inference while obtaining even higher scores than running the original model directly (**21.2 -> 24.4**). In the 1M context scenario on a single 24GB GPU, KTransformers can similarly achieve a 16 tokens/s inference speed, nearly 10 times faster than llama.cpp under the same conditions, with the "needle in haystack" evaluation score even surpassing the original model (**89.31 -> 92.88**).
|
||||
|
||||
Project url: https://github.com/kvcache-ai/ktransformers
|
||||
|
||||
## Mathematical Principle: The computational overhead of long-text inference and the sparsity in Attention caused by Softmax.
|
||||
|
||||
As the demand for longer context windows increases, not only have commercial large models like Kimi and Claude/Gemini started supporting increasingly longer context windows, but open-source models have also begun to catch up. Notably, both ChatGLM 4 and InternLM 2.5 have released versions that are under 10 billion parameters but support up to 1 million tokens of context. However, despite the relatively small size of these models, the enormous KVCache required for such ultra-long contexts still prevents local users from practically running these models. As shown in the figure below, while the InternLM2.5-7B-Chat-1M model weights only require 15.49GB of GPU memory, an additional 145.49GB is needed to store the entire 1M-token KVCache, which is clearly beyond the memory capacity of local users. Even when using the KVCache Offload feature of llama.cpp to offload the KVCache to CPU/DRAM, barely making the model runnable, performance remains unacceptable due to the need to fully scan the entire KVCache each time a single token is generated.
|
||||
|
||||
| <img title="" src="../assets/internlm_memory.png" alt="internlm_memory" width="882"> | <img src="../assets/SparQ_attention.png" title="" alt="sparQ" width="691"> |
|
||||
| ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
||||
|
||||
Fortunately, many studies have noticed that attention distribution during the inference phase tends to be **sparse**. For example, the right figure shows SparQ's experimental statistics based on LLaMa 7B, where less than 1% of tokens in a 3k context have relatively high attention scores. Similar conclusions are not only reflected in many other papers, such as H2O, Quest, InfLLM, and SnapKV, but we have also further validated this through long-text experiments with InternLM 2.5-7B-1M. Although the proportion isn't as extreme as 1%, due to the inherent head-focused effect of the softmax operation in attention mechanisms, it is theoretically possible that if we can identify in advance which tokens have high attention scores, scanning less than 5% of the tokens would suffice to essentially replicate the original result.
|
||||
|
||||
Thus, the problem narrows down to how to quickly identify these tokens with high attention scores without scanning them all. In the following sections, we will first briefly survey several key related papers, then summarize and propose a general framework we designed and implemented within KTransformers—a highly efficient sparse attention operator for CPUs.
|
||||
|
||||
## Related Papers and Conclusions
|
||||
|
||||
### Prune or Retrieval?
|
||||
|
||||
Based on the aforementioned points, we studied papers from recent years related to sparse selection in KVCache. The earliest of these is the paper H2O, which suggested that the attention distribution during inference is sparse and that only 5% of the KVCache is needed during inference. Following this, a series of works built on H2O's approach by designing more complex methods for selecting tokens that perform better in different scenarios. These methods are quite reasonable for single-word inference. However, as we previously explored in the Mooncake project, **we believe that the future trend is to precompute reusable KVCache as much as possible, and then use it to answer different questions.** This "compute once, use many" approach aims to reduce computational costs. Therefore, with this goal in mind, we prefer not to delete any tokens from the KVCache, or at least not remove a significant portion of them, to ensure that different questions can focus on different parts of the context in the future.
|
||||
|
||||

|
||||
|
||||
We further investigated related research, among which InfLLM proposed a very promising framework. Not only does it recognize that attention is sparse, but it also suggests that overly long contexts can cause attention to be dispersed into irrelevant noise, thereby reducing the model's ability to focus on key information. To address this issue, InfLLM introduces an external memory module (Memory Units) to store the context's KVCache. In each computation step, the most relevant semantic information is retrieved from this external memory module to participate in the calculation, thus enhancing the model's ability to handle long-context inference.
|
||||
|
||||
Specifically, InfLLM organizes the external memory module using semantic blocks composed of neighboring tokens and employs a sliding window mechanism during computation. In each step, it selects only the semantic blocks at the head of the context (Initial Tokens), the blocks near the current token (Local Tokens), and a few blocks with the highest semantic similarity to the current token to participate in the attention calculation. As shown in equation 1, to efficiently retrieve the blocks with the highest similarity, InfLLM selects a few representative tokens whose scores $$r_m$$ are the highest within each block. Use Equation 2 to calculate the semantic similarity between the current token and each semantic block.
|
||||
|
||||

|
||||
|
||||
Compared to the previously mentioned H2O, the differences in InfLLM are as follows:
|
||||
|
||||
1. The KVCache is not discarded but stored in memory and dynamically loaded onto the GPU during inference.
|
||||
|
||||
2. KVCache is managed at the granularity of blocks rather than tokens, with each block selecting a few tokens as its representative index tokens.
|
||||
|
||||
InfLLM's proposed method aligns with our "compute once, use many" approach of reusing KVCache. The external memory units in this method can be offloaded to CPU/DRAM or even SSD storage, allowing different parts to be selected for computation based on the specific question. This significantly improves the efficiency of attention computation.
|
||||
|
||||
### Other Improvements
|
||||
|
||||
Similarly, after InfLLM, Quest also manages tokens at the granularity of blocks. Quest analyzed the recall rate of key tokens in H2O and full attention, finding that the Top-10 attention score token recall rate for the H2O algorithm is around 50%, which indicates that too much key information was lost. To improve the recall rate of key tokens, Quest chooses two "representative tokens" from each block for retrieval. In the prefill stage, each KVCache block records the maximum and minimum values for each channel, as shown in the figure below under "Reduced Keys," which contains the element-wise min key and element-wise max key.
|
||||
|
||||
During the attention computation stage, the dot product is computed between the current query vector and the max key and min key of each KVCache block, respectively. Then, for each channel, the maximum value between the two resulting product vectors is selected and summed to serve as the upper bound of the relevance score for that KVCache block, as shown in stage 1 of the diagram. Based on the relevance scores, the top-k KVCache blocks are selected to participate in the attention computation, as illustrated in stage 2 of the diagram.
|
||||
|
||||

|
||||
|
||||
Compared to InfLLM, Quest does not take heterogeneous architectures into account. Instead, it assumes that all KVCache can still fit into memory, simply leveraging sparse attention to accelerate the inference process. Ultimately, Quest achieves a 7.03x speedup in attention computation and a 2.23x improvement in end-to-end inference latency.
|
||||
|
||||
Going further, SnapKV proposes retaining two parts of the tokens during the prefill stage, as shown in the diagram below with the orange and green segments. The difference from InfLLM lies only in the method of selecting the middle tokens. SnapKV selects tokens at the token level rather than the block level, with the score calculation being similar to H2O, i.e., $$softmax(\frac{qk^T}{\sqrt{d_k}})$$. However, when summing across columns, only the rows within the final green window are selected for computation, corresponding to the Local Tokens section in InfLLM. Additionally, SnapKV introduces a pooling operation on top of attention, which the paper explains as ensuring that the recalled tokens retain more complete semantic information.
|
||||
|
||||
This approach in SnapKV involves a one-time selection during the inference phase, after which only the selected tokens are used for attention computation, while the rest of the KVCache is discarded.
|
||||
|
||||

|
||||
|
||||
|
||||
Other related papers include PyramidKV, which observed that attention scores exhibit a pyramid-shaped distribution across attention layers. In lower attention layers, attention is widely distributed, while in higher layers, the attention scores for a few key tokens become increasingly prominent. Therefore, PyramidKV allocates more KVCache storage space to lower layers and less space to higher layers.
|
||||
|
||||
MagicPiG, based on Locality-Sensitive Hashing (LSH), proposes a dynamic KVCache management strategy. First, it uses SnapKV to select a portion of important tokens to be stored in the GPU, while the KVCache of other tokens is placed in memory. By leveraging the high efficiency of LSH in high-dimensional space searches and the multithreading capabilities of CPUs, MagicPiG retrieves KVCache from memory that is similar to the current query and loads it into memory for inference. Compared to the earlier methods like InfLLM, Quest, and SnapKV, MagicPiG does not need to scan all representative tokens and select the top-k KVCache. Instead, it utilizes the mathematical properties of LSH, which not only simulates attention scores but also allows for identifying important KVCache with low overhead and high speed.
|
||||
|
||||
The above are just descriptions of some key points. For more detailed explanations, you can refer to the existing articles on Zhihu in Chinese:
|
||||
|
||||
- https://zhuanlan.zhihu.com/p/701580870
|
||||
|
||||
- https://zhuanlan.zhihu.com/p/714288577
|
||||
|
||||
## KTransformers CPU Sparse Attn Framework
|
||||
|
||||
### Framework Prototype
|
||||
|
||||
Based on the introduction of the above papers, we have distilled the following key points:
|
||||
|
||||
- The distribution of attention weights is sparse, and useless KVCache may introduce noise, which could actually reduce performance during the inference stage.
|
||||
|
||||
- For the KVCache eviction strategy during the inference stage, the common approach is to retain the tokens from the beginning and the end of the prompt, while designing algorithms to select the tokens from the middle portion. One of the main factors affecting the model's performance is the ability to accurately identify the key tokens.
|
||||
|
||||
- Managing the middle portion of tokens in blocks can improve memory swapping and attention computation efficiency, and smaller blocks do not seem to perform worse than token-level granularity.
|
||||
|
||||
- The tokens that each attention layer focuses on during inference differ, and even the allocated KVCache capacity for different layers should vary.
|
||||
|
||||
Based on these insights and inspirations, we developed a general framework for implementing sparse CPU attention operators during the inference phase. In the prefill stage, we use chunked prefill, loading only one layer of KVCache into GPU memory at a time for computation. Once completed, the KVCache is stored on CPU/DRAM. In the subsequent decode stage, instead of swapping KVCache in and out, the sparse attention operator runs directly on the CPU. **This significantly reduces the minimum** **GPU** **memory requirements, making local 128K or even 1M token contexts possible.**
|
||||
|
||||
Specifically during the generation phase, we implemented the entire framework as shown in the diagram below.
|
||||
|
||||

|
||||
|
||||
We organized the KVCache in units of blocks. Specifically:
|
||||
|
||||
- **KVCache Partitioning:** A complete input prompt is divided into three configurable parts: Initial, Context, and Local. During the computation process, the Initial/Local parts will be fully attended to, while the Context part will be sparsely retrieved. This approach is based on findings from many papers (such as streamingLLM and Minference) which mention the existence of "attention sinks," where higher attention weights are often found at the beginning and the end of the sequence.
|
||||
|
||||
- **Context Block Partitioning:** For the middle Context, we follow the InfLLM approach by dividing it into blocks based on a configurable fixed number of tokens. Each block can select 1 to k tokens as its representative tokens. During the actual inference phase, the Context blocks that require attention are selected based on these representative tokens.
|
||||
|
||||
- Specifically, we have implemented the following methods for selecting representative tokens, based on the approaches outlined in various papers.
|
||||
|
||||
- Max: The maximum values of multiple tokens within a block, across each channel, are concatenated to form the representative token for the current block.
|
||||
|
||||
- Mean: The average values of multiple tokens within a block, across each channel, are concatenated to form the representative token for the current block.
|
||||
|
||||
- Quest: A combination of the previous two methods: the maximum and minimum values of multiple tokens within a block, across each channel, are taken as the representative tokens for the block. Under this method, the number of representative tokens is fixed at 2
|
||||
|
||||
- Dynamic: By calculating the cumulative attention score for each token using a specific method, each block selects the top-k tokens with the highest scores as the representative tokens for the block. This is similar to InfLLM but with some simplifications.
|
||||
|
||||
- Fix: Select tokens at fixed intervals within the block.
|
||||
|
||||
- Once the representative tokens for each block are determined, use Equation 2 from InfLLM to calculate the similarity between the input X and the k representative tokens of each block B, and only select the top $$r_k$$ blocks for attention computation, where $$l_P $$ represents the length of the historical tokens:
|
||||
|
||||
Since InfLLM requires calculating a representative score for each token during the prefill stage and then selecting a representative token for each block based on these scores, this operation involves invasive modifications to the prefill implementation, making it difficult to integrate with other methods. Furthermore, in actual testing, we found that in most scenarios, similar or even better results can be achieved through a combination of other methods. Therefore, we ultimately decided not to integrate this method into the framework.
|
||||
|
||||
## Further Optimizations
|
||||
|
||||
After implementing the above framework, we conducted a series of evaluations based on LongBench and InfiniteBench.
|
||||
|
||||
At the beginning of the experiment, we designed the architecture so that for each inference token, the most relevant KVCache blocks would be reselected. On the one hand, this strategy incurred significant overhead during the retrieval process. On the other hand, we found that in some scenarios, f**requently changing the selection of retrieved blocks did not lead to better results**. For example, in the kvretrieval dataset, we observed that the model's responses were often correct in the first half but incorrect in the second half. Since the answers to kvretrieval questions consist of long and meaningless strings, this indicates that the correct KVCache blocks were selected during the inference of the earlier tokens but incorrect blocks were chosen during the later stages of inference.
|
||||
|
||||
To address this issue, we further integrated the method proposed in SnapKV. Before starting the inference, we preselect relevant KVCache blocks by analyzing the attention scores of the context tokens, based on the question. During the subsequent inference stages, the selection of KVCache blocks is restricted to this preselected range. This approach allowed us to select the block containing the correct answer 100% of the time in the kvretrieval dataset.
|
||||
|
||||
However, it should be noted that this method strictly relies on the structure of the Benchmark Prompt and **does not necessarily guarantee optimal performance in other scenarios, such as complex document understanding and generation tasks.** Therefore, we have integrated it into our framework as an optional module. The final framework and configurable parameters are as follows:
|
||||
|
||||

|
||||
|
||||
|
||||
Configuration:
|
||||
|
||||
- **threads_num:** Number of CPU Threads
|
||||
|
||||
- **block_size:** KVCache Block Size
|
||||
|
||||
- **local_windows_len:** Prompt End Window Size
|
||||
|
||||
- **preselect_block_count:** Number of Preselected Blocks
|
||||
|
||||
- **second_block_count:** Number of Blocks Selected After Preselection
|
||||
|
||||
- **preselect_block:** Whether to Enable Preselection
|
||||
|
||||
- **token_step:** Interval Between Token Selections for KVCache
|
||||
|
||||
- **layer_step:** Interval Between Layer Selections for KVCache
|
||||
|
||||
- **dense_layer_num:** Number of Initial Layers Without KVCache Selection, Importing All KVCache
|
||||
|
||||
- **head_select_mode:SEPARATE**(In the GQA scenario, each kv_head is selected separately) / **SHARED:** (All kv_heads are selected together)
|
||||
|
||||
- **representative_type:** Method of Selecting Representative Tokens
|
||||
|
||||
- **representative_num:** Number of Representative Tokens
|
||||
|
||||
By modifying configuration options, various KVCache eviction or compression methods can be easily reproduced within our framework. For example:
|
||||
|
||||
- Setting `block_size` to 1 and `preselect_block` to True results in a version of SnapKV without the pooling operation.
|
||||
|
||||
- Setting `representative_type` to Quest, `preselect_block` to False, and `head_select_mode` to SEPARATE replicates the Quest method.
|
||||
|
||||
Below is the pseudocode for the framework:
|
||||
|
||||
```python
|
||||
def preselect_block(local_q, kvcache):
|
||||
key_states = kvcache.keycache
|
||||
attn_scores = torch.matmul(
|
||||
local_q, key_states.transpose(2, 3)
|
||||
) / math.sqrt(head_dim)
|
||||
attn_scores += attn_mask
|
||||
attn_scores = nn.functional.softmax(
|
||||
attn_scores, dim=-1, dtype=torch.float32
|
||||
).to(query_states.dtype)
|
||||
vote = attn_scores[..., initial_size:-local_size:, :].sum(dim=-2)
|
||||
pool_vote = pool1d(vote, kernel_size=kernel_size, padding=kernel_size//2, stride=1)
|
||||
indices = pool_vote.topk(max_capacity_prompt - local_size, dim=-1).indices
|
||||
kv_cache_block_indices = find_representative_tokens_block(indices)
|
||||
kvcache_after_preselected = kvcache[kv_cache_block_indices]
|
||||
...
|
||||
return kvcache_after_preselected
|
||||
def get_representative_tokens():
|
||||
Calculate the representative token for each block based on the representative_type.
|
||||
return ...
|
||||
def decode_attention(query, key, value):
|
||||
# Select once every token_steps tokens.
|
||||
token_steps = 4
|
||||
# Select once every layer_steps layers.
|
||||
layer_steps = 4
|
||||
for token_idx in range(max_new_tokens):
|
||||
for layer_idx in range(config.num_hidden_layers):
|
||||
if token_idx % token_steps != 0 or layer_idx % layer_steps != 0:
|
||||
# If the attention of the current layer in this round does not require reselection, the historical selection results from the kvcache will be retained.
|
||||
kvcache_after_retrieval = history_kvcache_after_retrieval[layer_idx//layer_steps]
|
||||
else:
|
||||
# Otherwise, use the query from the current round's current layer to reselect the kvcache.
|
||||
kvcache_after_retrieval = retrieval_kvcache(query, kvcache)
|
||||
# Save it to the kvcache historical selection results.
|
||||
history_kvcache_after_retrieval[layer_idx//layer_steps] = kvcache_after_retrieval
|
||||
# calculate attention
|
||||
output = attn(query, kvcache_after_retrieval)
|
||||
yield output
|
||||
|
||||
# Model prefill, if preselection is required, local_q still needs to be saved.
|
||||
local_q, KVCache = model.prefill(input_ids)
|
||||
if preselect_block:
|
||||
# Preselection round
|
||||
KVCache = preselect_block(local_q, kvcache)
|
||||
# Find the representative token for each block.
|
||||
block_representative_tokens = get_representative_tokens(
|
||||
kvcache,
|
||||
config.representative_type
|
||||
)
|
||||
|
||||
# model generate
|
||||
'''
|
||||
'''
|
||||
decode_attention(query, key, value)
|
||||
'''
|
||||
'''
|
||||
```
|
||||
|
||||
## Experiment
|
||||
|
||||
At the beginning of testing, we will use the following basic configuration, which will be further optimized through the extended framework.
|
||||
|
||||
```python
|
||||
max_seq_len: 256000 # KVCache length
|
||||
block_size: 128 # KVCache block size
|
||||
local_windows_len: 4096 # The KVCache of length local_windows_len is stored on the GPU.
|
||||
second_block_count: 96 # After preselection, each time select the number of KVCache blocks. If >= preselect_block_count, use the preselected blocks.
|
||||
threads_num: 64 # CPU thread num
|
||||
representative_type: DYNAMIC # KVCache block representative token selection method.
|
||||
kv_type: FP16
|
||||
dense_layer_num: 0 # The first few layers do not need to fill or select KVCache
|
||||
representative_num: 1 # The number of representative tokens within a KVCache block.
|
||||
preselect_block: False # Whether to preselect.
|
||||
head_select_mode: SHARED # All kv_heads jointly select.
|
||||
preselect_block_count: 0 # Number of preselected blocks.
|
||||
layer_step: 1 # Select every few layers.
|
||||
token_step: 1 # Select every few tokens.
|
||||
```
|
||||
|
||||
Under our framework, the comparison between the original model and KTransformers after acceleration on datasets such as 128K Big Needle-in-a-Haystack, passkey, kvretrieval, etc., is as follows. The passkey dataset involves inserting a small segment of numbers at varying depths within a redundant text. kvretrieval is about finding a matching item in randomly generated key-value pairs. All tests were conducted under the opencompass framework:
|
||||
|
||||

|
||||
|
||||
| | | | |
|
||||
| ----------------------------------------------------------- | ------------------------------- | ------- | ----------- |
|
||||
| | Single needle retrieval zh 128k | passkey | kvretrieval |
|
||||
| Original model | 99.89 | 100 | 21.0 |
|
||||
| KTransformers (reselect KVCache blocks for each generation) | 100 | 100 | 15.40 |
|
||||
|
||||
We can see that both the original model and the accelerated KTransformers achieve perfect scores on the relatively simpler datasets, such as Single Needle Retrieval and passkey. At the same time, the generation speed has significantly improved, increasing from 4.86 tokens/s with llama.cpp to 27.49 tokens/s with KTransformers, achieving up to a 5.65x speedup. Although the current configuration shows a noticeable drop in performance on the more challenging kvretrieval dataset, in the next section, we will address this by implementing a more optimized selection strategy to compensate for or even surpass the original model's accuracy.
|
||||
|
||||
Additionally, we tested the performance of the KTransformers-based configuration framework in reproducing the results of Quest. However, since InternLM2.5-7B-Chat-1M uses GQA (Grouped Query Attention) while the Quest paper primarily focuses on optimizing MHA (Multi-Head Attention) models, the actual testing results were not particularly favorable. The official team also mentioned that further support for GQA models is needed, so we will not discuss this in detail for now.
|
||||
|
||||
### Further improve performance
|
||||
|
||||
By modifying certain configurations within our flexible framework on the basis of reproduction, **we can actually achieve better results than those reported in the previous paper,** as shown in the figure below:
|
||||
|
||||

|
||||
|
||||
As mentioned earlier, the goal of the kvretrieval dataset is to find a matching key-value pair within a long sequence of semantically meaningless pairs. If tokens are generated by reselecting based on the current query each time, the likelihood of deviation increases as the text grows, leading to the selection of different KVCache blocks compared to previous selections. To address this, we introduced a preselection mechanism using SnapKV to calculate the method for selecting representative tokens, which preselects a portion of the KVCache blocks. During the subsequent inference process, the selection is limited to these blocks. After one round of preselection, the score increased from 15.4 to 24.2, **surpassing the original model + full attention's performance of 21 points.** Further research indicates that the sparsity effect of the KVCache in the first few layers of LLMs is not as significant. Therefore, we set the first two layers to fully reuse the KVCache, ultimately achieving a score of **24.4**.
|
||||
|
||||
Similarly, when testing the needle-in-a-haystack task on the 1M dataset, we not only reproduced the original model's reported score but also further improved accuracy (**from 89.31 to 92.88**) by using the KTransformers CPU Sparse Attn Framework to selectively compute only certain KVCache blocks. Additionally, the inference speed **reached nearly 10 times that of llama.cpp**.
|
||||
|
||||

|
||||
|
||||
### More comparisons
|
||||
|
||||
As shown in the two figures below, using the Single Needle Retrieval dataset as an example, we set llama.cpp to store the KVCache on CPU/DRAM while performing all computations on the GPU. On a 4090D server, we compared the KTransformers CPU Sparse Attn Framework with llama.cpp. While maintaining **100% answer accuracy**, we achieved a 20.6 to 94.1 times prefill speed increase and a **1.2 to 7.1 times inference speed boost**.
|
||||
|
||||
|  |  |
|
||||
| --------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
|
||||
The main reason for the significant gap in prefill speed is that after enabling KVCache offload, llama.cpp performs the attention (attn) computation on the CPU. In long-text scenarios, attention not only requires heavy computation but also takes up the majority of the computation time. In contrast, KTransformers leverages a flexible template injection framework to implement GPU Chunk Prefill layer by layer. Moving forward, we plan to further integrate high-performance sparse prefill methods such as MInference to boost speed even further.
|
||||
|
||||
Additionally, as a key focus of this article, the right-hand graph shows that as the prompt length increases, the inference speed of KTransformers remains stable, hovering near a horizontal line. In contrast, llama.cpp slows down as the prompt length increases. By selecting only the most important 16K KVCache blocks to participate in the inference computation, KTransformers maintains a consistent inference speed comparable to llama.cpp when processing a 16K prompt, without any performance degradation (at least on these test datasets).
|
||||
|
||||
## How to Use
|
||||
|
||||
Currently, long context is only supported by our **local_chat.py** interface, and the integration with the server interface is under development.
|
||||
|
||||
To facilitate user management, we have uploaded the model config, gguf, and tokenizer to a repo. URL: https://huggingface.co/nilv234/internlm2_5_to_llama_1m/tree/main
|
||||
|
||||
By setting the model_path and gguf_path in the local_chat function to **/path/to/repo** and setting the mode to **"long_context"**, you can use the InternLM2.5-7B-Chat-1M model with 1m functionality on a 24G VRAM.
|
||||
|
||||
After running local_chat.py for the first time, a config.yaml file will be automatically created under ** ~/.ktransformers**. The relevant configurations for long context are as follows:
|
||||
|
||||
```python
|
||||
chunk_size: 4096 # prefill chunk size
|
||||
max_seq_len: 100000 # KVCache length
|
||||
block_size: 128 # KVCache block size
|
||||
local_windows_len: 4096 # The KVCache of length local_windows_len is stored on the GPU.
|
||||
second_select_num: 96 # After preselection, each time select the number of KVCache blocks. If >= preselect_block_count, use the preselected blocks.
|
||||
threads_num: 64 # CPU thread num
|
||||
anchor_type: DYNAMIC # KVCache block representative token selection method.
|
||||
kv_type: FP16
|
||||
dense_layer_num: 0 # The first few layers do not need to fill or select KVCache
|
||||
anchor_num: 1 # The number of representative tokens within a KVCache block.
|
||||
preselect_block: False # Whether to preselect.
|
||||
head_select_mode: SHARED # All kv_heads jointly select.
|
||||
preselect_block_count: 96 # Number of preselected blocks.
|
||||
layer_step: 1 # Select every few layers.
|
||||
token_step: 1 # Select every few tokens.
|
||||
```
|
||||
|
||||
The memory required for different context lengths is shown in the table below:
|
||||
|
||||
| | 4K | 32K | 64K | 128K | 512K | 1M |
|
||||
| -------------- | --- | ---- | ---- | ---- | ---- | ------ |
|
||||
| DRAM Size (GB) | 0.5 | 4.29 | 8.58 | 17.1 | 68.7 | 145.49 |
|
||||
|
||||
Please choose an appropriate max_seq_len based on your DRAM size.
|
||||
For example:
|
||||
```python
|
||||
python local_chat.py --model_path="/data/model/internlm2_5_to_llama_1m" --gguf_path="/data/model/internlm2_5_to_llama_1m" --max_new_tokens=500 --cpu_infer=10 --use_cuda_graph=True --mode="long_context" --prompt_file="/path/to/file"
|
||||
```
|
||||
|
||||
If you've already specified the input text via the prompt_file, just press Enter when the terminal displays chat: to begin.
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
## How to use ktransformers long context framework
|
||||
|
||||
Currently, long context is only supported by our **local_chat.py** interface, and the integration with the server interface is under development.
|
||||
|
||||
To facilitate user management, we have uploaded the model config, gguf, and tokenizer to a repo. URL: https://huggingface.co/nilv234/internlm2_5_to_llama_1m/tree/main
|
||||
|
||||
By setting the model_path and gguf_path in the local_chat function to **/path/to/repo** and setting the mode to **"long_context"**, you can use the InternLM2.5-7B-Chat-1M model with 1m functionality on a 24G VRAM.
|
||||
|
||||
After running local_chat.py for the first time, a config.yaml file will be automatically created under ** ~/.ktransformers**. The relevant configurations for long context are as follows:
|
||||
|
||||
```python
|
||||
chunk_size: 4096 # prefill chunk size
|
||||
max_seq_len: 100000 # KVCache length
|
||||
block_size: 128 # KVCache block size
|
||||
local_windows_len: 4096 # The KVCache of length local_windows_len is stored on the GPU.
|
||||
second_select_num: 96 # After preselection, each time select the number of KVCache blocks. If >= preselect_block_count, use the preselected blocks.
|
||||
threads_num: 64 # CPU thread num
|
||||
anchor_type: DYNAMIC # KVCache block representative token selection method.
|
||||
kv_type: FP16
|
||||
dense_layer_num: 0 # The first few layers do not need to fill or select KVCache
|
||||
anchor_num: 1 # The number of representative tokens within a KVCache block.
|
||||
preselect_block: False # Whether to preselect.
|
||||
head_select_mode: SHARED # All kv_heads jointly select.
|
||||
preselect_block_count: 96 # Number of preselected blocks.
|
||||
layer_step: 1 # Select every few layers.
|
||||
token_step: 1 # Select every few tokens.
|
||||
```
|
||||
|
||||
The memory required for different context lengths is shown in the table below:
|
||||
|
||||
| | 4K | 32K | 64K | 128K | 512K | 1M |
|
||||
| -------------- | --- | ---- | ---- | ---- | ---- | ------ |
|
||||
| DRAM Size (GB) | 0.5 | 4.29 | 8.58 | 17.1 | 68.7 | 145.49 |
|
||||
|
||||
Please choose an appropriate max_seq_len based on your DRAM size.
|
||||
For example:
|
||||
```python
|
||||
python local_chat.py --model_path="/data/model/internlm2_5_to_llama_1m" --gguf_path="/data/model/internlm2_5_to_llama_1m" --max_new_tokens=500 --cpu_infer=10 --use_cuda_graph=True --mode="long_context" --prompt_file="/path/to/file"
|
||||
```
|
||||
|
||||
If you've already specified the input text via the prompt_file, just press Enter when the terminal displays chat: to begin.
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
# Makefile
|
||||
## Target
|
||||
### flake_find:
|
||||
```bash
|
||||
make flake_find
|
||||
```
|
||||
find all the python files under ./ktransformers dir and find the Error, Warning, Fatal... (their codes) into a list that are not consistent with the pep8 standard. For now we have get all this list in the .flake8 file's extend-ignore section in order to let flakes8 ignore them temporarily.(we may improve them in the future)
|
||||
### format:
|
||||
```bash
|
||||
make format
|
||||
```
|
||||
we use black to format all the python files under ./ktransformers dir. It obeys the pep8 standard
|
||||
but we modify the line length to 120 by add
|
||||
```toml
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
preview = true
|
||||
unstable = true
|
||||
```
|
||||
in the pyproject.toml file.
|
||||
|
||||
### dev_install:
|
||||
```bash
|
||||
make dev_install
|
||||
```
|
||||
install the package in the development mode. It means that the package is installed in the editable mode. So if you modify the code, you don't need to reinstall the package. We recommend the developer to use this method to install the package.
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
|
||||
# Muti-GPU
|
||||
|
||||
Assume you have read the [Injection Tutorial](./injection_tutorial.md) and have a basic understanding of how to inject a model. In this tutorial, we will show you how to use KTransformers to run a model on multiple GPUs.
|
||||
|
||||
If you have multiple GPUs, you can set the device for each module to different GPUs.
|
||||
DeepseekV2-Chat got 60 layers, if we got 2 GPUs, we can allocate 30 layers to each GPU. Complete multi GPU rule examples [here](https://github.com/kvcache-ai/ktransformers/blob/main/ktransformers/optimize/optimize_rules/DeepSeek-V3-Chat-multi-gpu.yaml).
|
||||
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<img alt="Inject-Struction" src="../assets/multi_gpu.png" width=60%>
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
First of all, for multi-GPU, we have to inject an new operator `KDeepseekV2Model`. And set division of the layers to different GPUs. For our case, we have to set the `transfer_map` in the `KDeepseekV2Model` operatoras as follows:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model$"
|
||||
replace:
|
||||
class: "ktransformers.operators.models.KDeepseekV2Model"
|
||||
kwargs:
|
||||
transfer_map:
|
||||
30: "cuda:1"
|
||||
```
|
||||
|
||||
And we have to set the device for each module in the model.
|
||||
|
||||
For example, for `routed experts`, the yaml for one GPU is:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # Custom MoE kernel with expert parallelism
|
||||
kwargs:
|
||||
generate_device: "cuda:0"
|
||||
generate_op: "MLPCUDAExperts"
|
||||
out_device: "cuda:0"
|
||||
recursive: False # Don't recursively inject submodules of this module
|
||||
```
|
||||
But for two GPUs, we need to set the device for each module in the model.
|
||||
|
||||
```yaml
|
||||
# allcate 0-29 layers‘s out_device to cuda:0
|
||||
- match:
|
||||
name: "^model\\.layers\\.(0|[1-9]|[12][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert paralleism
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:0"
|
||||
recursive: False # don't recursively inject submodules of this module
|
||||
|
||||
# allocate 30-59 layers‘s out_device to cuda:1
|
||||
- match:
|
||||
name: "^model\\.layers\\.([345][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert paralleism
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:1"
|
||||
recursive: False # don't recursively inject submodules of this module
|
||||
```
|
||||
For other modules, we can set the device in the same way.
|
||||
|
||||
# How to fully utilize multi-GPU's VRAM
|
||||
|
||||
When you have multiple GPUs, you can fully utilize the VRAM of each GPU by moving more weights to the GPU.
|
||||
|
||||
For example, for DeepSeekV2-Chat, we can move the weights of the experts to the GPU.
|
||||
|
||||
For example, the yaml for two GPUs is:
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\.(0|[1-9]|[12][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:0"
|
||||
recursive: False
|
||||
```
|
||||
|
||||
But we got extra 60GB VRAM on cuda:0, we can move experts in layer 4~8 to cuda:0.
|
||||
|
||||
```yaml
|
||||
# Add new rule before old rule.
|
||||
- match:
|
||||
name: "^model\\.layers\\.([4-8])\\.mlp\\.experts$" # inject experts in layer 4~8 as marlin expert
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts
|
||||
kwargs:
|
||||
generate_device: "cuda:0"
|
||||
generate_op: "KExpertsMarlin"
|
||||
recursive: False
|
||||
|
||||
- match:
|
||||
name: "^model\\.layers\\.(0|[1-9]|[12][0-9])\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts
|
||||
kwargs:
|
||||
generate_device: "cpu"
|
||||
generate_op: "KExpertsCPU"
|
||||
out_device: "cuda:0"
|
||||
recursive: False
|
||||
```
|
||||
|
||||
Adjust the layer range as you want. Note that:
|
||||
* The loading speed will be significantly slower for each expert moved to the GPU.
|
||||
* You have to close the cuda graph if you want to move the experts to the GPU.
|
||||
* For DeepSeek-R1/V3, each expert moved to the GPU will consume approximately 6GB of VRAM.
|
||||
* The first matched rule in yaml will be applied. For example, if you have two rules that match the same layer, only the first rule's replacement will be valid.
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 369 KiB |
|
Before Width: | Height: | Size: 204 KiB |
|
|
@ -1,35 +0,0 @@
|
|||
# Llamafile Operators Documentation
|
||||
|
||||
## Llamafile Sgemm
|
||||
|
||||
The Llamafile Sgemm module is an efficient implementation of general matrix multiplication (GEMM) extracted from the great [Llamafile project](https://github.com/Mozilla-Ocho/llamafile/blob/main/llamafile/sgemm.cpp).
|
||||
This module optimizes performance by utilizing various processor-specific instruction sets. For instance, it checks for different x86 instruction sets such as AVX, FMA, and AVX512, leveraging these advanced instructions to accelerate computation.
|
||||
Additionally, the Llamafile Sgemm module supports multiple quantization types, including q8_0, q6_k, and q5_k, among others. This adaptability to different hardware capabilities ensures the most advanced instructions are used in any given computing environment, achieving high computational efficiency. For more information, you can view the [Llamafile Sgemm module](https://github.com/Mozilla-Ocho/llamafile/blob/main/llamafile/sgemm.cpp) on GitHub.
|
||||
|
||||
|
||||
## CPUInfer
|
||||
To power Llamafile and many future CPU kernels without the original GGML framework, we developed a simple CPUInfer multi-threaded execution framework. It currently leverages the Llamafile Sgemm module to implement key operators such as linear layers, MLP, and MoE, and will be extended to support many other operators. These operators are fundamental components for building large models. CPUInfer features a backend work-stealing thread pool and asynchronous task queue execution logic to efficiently offload parts of model parameters to the CPU, thereby maintaining high inference performance. It supports adjustments based on hardware capabilities or user configurations, providing enhanced inference performance and making it an ideal tool for running deep learning models on CPUs.
|
||||
|
||||
## Expert-Parallel MoE
|
||||
|
||||
The MoE module's performance can be enhanced by using custom kernels that utilize **expert parallelism**. Since the routed experts are independently computable, we can utilize this inherent parallelism to speed up MoE computations. Specifically, we can allocate each expert MLP to a separate thread group, allowing for the simultaneous computation of all routed experts. This approach of expert parallelism significantly boosts MoE performance by minimizing the frequency of global synchronizations and reducing kernel launch overhead compared to sequential expert computation.
|
||||
|
||||
## Microbenchmark
|
||||
|
||||
Our evaluations were conducted on an Intel(R) Xeon(R) Gold 6454S processor, utilizing real parameters from the DeepSeek-Coder-V2-Instruct model.
|
||||
|
||||
### Linear Projection
|
||||
|
||||
The performance of the linear layer was assessed using an Attention Output Projection with dimensions of [5120, 16384]. Here, the input was a vector of 16384 dimensions, and the output was a vector of 5120 dimensions.
|
||||
|
||||

|
||||
|
||||
As we can see, in half-precision floating-point formats (fp16 and bf16), CPUInfer's performance exceeded that of Torch by 1.7 and 1.5 times, respectively. For 8-bit quantization, CPUInfer (supporting q8_0) and Torch (supporting qint8) demonstrated nearly equivalent performance. However, CPUInfer employs a more refined scaling approach, using different factors for each group (in q8_0 quantization, every 32 numbers form one group), whereas Torch uses a basic per-tensor quantization, potentially leading to significant precision loss. Furthermore, CPUInfer’s capability to use lower-bit quantization enhances inference speed in specific scenarios.
|
||||
|
||||
### MoE
|
||||
|
||||
In the MoE module, each token selected 6 experts out of 160 for computation, with input and output dimensions of 5120, and an intermediate dimension of 1536.
|
||||
|
||||

|
||||
|
||||
For half-precision floating points and 8-bit quantization formats, CPUInfer's generation performance was 2.5 and 3.2 times better than Torch, respectively. Moreover, using the 8-bit quantization format, CPUInfer achieved faster prefill speeds compared to Torch, with shorter prompts highlighting a more pronounced performance difference.
|
||||
|
|
@ -1,134 +0,0 @@
|
|||
# Intel GPU Support for KTransformers (Beta)
|
||||
|
||||
## Introduction
|
||||
|
||||
### Overview
|
||||
We are excited to introduce **Intel GPU support** in KTransformers (Beta release). This implementation has been tested and developed using Intel Xeon Scalable processors and Intel Arc GPUs (such as A770 and B580).
|
||||
|
||||
## Installation Guide
|
||||
|
||||
### 1. Install Intel GPU Driver
|
||||
Begin by installing the GPU drivers for your Intel GPU:
|
||||
- [Official GPU Installation Guide for Intel GPUs](https://dgpu-docs.intel.com/driver/overview.html)
|
||||
|
||||
To verify that the kernel and compute drivers are installed and functional:
|
||||
|
||||
```bash
|
||||
clinfo --list | grep Device
|
||||
`-- Device #0: 13th Gen Intel(R) Core(TM) i9-13900K
|
||||
`-- Device #0: Intel(R) Arc(TM) A770 Graphics
|
||||
`-- Device #0: Intel(R) UHD Graphics 770
|
||||
```
|
||||
|
||||
> [!Important]
|
||||
> Ensure that **Resizable BAR** is enabled in your system's BIOS before proceeding. This is essential for optimal GPU performance and to avoid potential issues such as `Bus error (core dumped)`. For detailed steps, please refer to the official guidance [here](https://www.intel.com/content/www/us/en/support/articles/000090831/graphics.html).
|
||||
|
||||
### 2. Set Up Conda Environment
|
||||
We recommend using Miniconda3/Anaconda3 for environment management:
|
||||
|
||||
```bash
|
||||
# Download Miniconda
|
||||
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
|
||||
|
||||
# Create environment
|
||||
conda create --name ktransformers python=3.11
|
||||
conda activate ktransformers
|
||||
|
||||
# Install required libraries
|
||||
conda install -c conda-forge libstdcxx-ng
|
||||
|
||||
# Verify GLIBCXX version (should include 3.4.32)
|
||||
strings ~/anaconda3/envs/ktransformers/lib/libstdc++.so.6 | grep GLIBCXX
|
||||
```
|
||||
|
||||
> **Note:** Adjust the Anaconda path if your installation directory differs from `~/anaconda3`
|
||||
|
||||
### 3. Install PyTorch and IPEX-LLM
|
||||
Install PyTorch with XPU backend support and [IPEX-LLM](https://github.com/intel/ipex-llm):
|
||||
|
||||
```bash
|
||||
pip install ipex-llm[xpu_2.6]==2.3.0b20250518 --extra-index-url https://download.pytorch.org/whl/xpu
|
||||
pip uninstall torch torchvision torchaudio
|
||||
pip install torch==2.7+xpu torchvision torchaudio --index-url https://download.pytorch.org/whl/test/xpu # install torch2.7
|
||||
pip uninstall intel-opencl-rt dpcpp-cpp-rt
|
||||
```
|
||||
|
||||
### 4. Build ktransformers
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule update --init
|
||||
|
||||
# Install dependencies
|
||||
bash install.sh --dev xpu
|
||||
```
|
||||
|
||||
## Running DeepSeek-R1 Models
|
||||
|
||||
### Configuration for 16B VRAM GPUs
|
||||
Use our optimized configuration for constrained VRAM:
|
||||
|
||||
```bash
|
||||
export SYCL_CACHE_PERSISTENT=1
|
||||
export ONEAPI_DEVICE_SELECTOR=level_zero:0
|
||||
export SYCL_PI_LEVEL_ZERO_USE_IMMEDIATE_COMMANDLISTS=1
|
||||
|
||||
python ktransformers/local_chat.py \
|
||||
--model_path deepseek-ai/DeepSeek-R1 \
|
||||
--gguf_path <path_to_gguf_files> \
|
||||
--optimize_config_path ktransformers/optimize/optimize_rules/xpu/DeepSeek-V3-Chat.yaml \
|
||||
--cpu_infer <cpu_cores + 1> \
|
||||
--device xpu \
|
||||
--max_new_tokens 200
|
||||
```
|
||||
|
||||
## Known Limitations
|
||||
- Serving function is not supported on Intel GPU platform for now
|
||||
|
||||
## Troubleshooting
|
||||
1. Best Known Config (BKC) to obtain best performance
|
||||
|
||||
To obtain best performance on Intel GPU platform, we recommend to lock GPU frequency and set CPU to performance mode by below settings.
|
||||
```bash
|
||||
echo "performance" | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
|
||||
echo 0 | sudo tee /sys/devices/system/cpu/cpu*/power/energy_perf_bias
|
||||
# 2400 is max frequency for Arc A770
|
||||
sudo xpu-smi config -d 0 -t 0 --frequencyrange 2400,2400
|
||||
# 2850 is max frequency for Arc B580
|
||||
# sudo xpu-smi config -d 0 -t 0 --frequencyrange 2850,2850
|
||||
```
|
||||
|
||||
2. Runtime error like `xpu/sycl/TensorCompareKernels.cpp:163: xxx. Aborted (core dumped)`
|
||||
|
||||
This error is mostly related to GPU driver. If you meet such error, you could update your `intel-level-zero-gpu` to `1.3.29735.27-914~22.04` (which is a verified version by us) by below command.
|
||||
```bash
|
||||
wget -qO - https://repositories.intel.com/gpu/intel-graphics.key | \
|
||||
sudo gpg --dearmor --output /usr/share/keyrings/intel-graphics.gpg
|
||||
echo "deb [arch=amd64,i386 signed-by=/usr/share/keyrings/intel-graphics.gpg] https://repositories.intel.com/gpu/ubuntu jammy client" | \
|
||||
sudo tee /etc/apt/sources.list.d/intel-gpu-jammy.list
|
||||
sudo apt update
|
||||
# or sudo apt update --allow-insecure-repositories
|
||||
sudo apt install intel-level-zero-gpu=1.3.29735.27-914~22.04
|
||||
```
|
||||
|
||||
3. `ImportError: cannot import name 'intel' from 'triton._C.libtriton'`
|
||||
|
||||
Installing Triton causes pytorch-triton-xpu to stop working. You can resolve the issue with following command:
|
||||
```bash
|
||||
pip uninstall triton pytorch-triton-xpu
|
||||
# Reinstall correct version of pytorch-triton-xpu
|
||||
pip install pytorch-triton-xpu==3.3.0 --index-url https://download.pytorch.org/whl/xpu
|
||||
```
|
||||
|
||||
4. `ValueError: Unsupported backend: CUDA_HOME ROCM_HOME MUSA_HOME are not set and XPU is not available.`
|
||||
|
||||
Ensure you have permissions to access /dev/dri/renderD*. This typically requires your user to be in the render group:
|
||||
```bash
|
||||
sudo gpasswd -a ${USER} render
|
||||
newgrp render
|
||||
```
|
||||
|
||||
## Additional Information
|
||||
To run KTransformers on XPU with Docker, please refer to [Docker_xpu.md](./Docker_xpu.md).
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
<!-- omit in toc -->
|
||||
|
||||
# GPT-4/o1 级别本地 VSCode Copilot 在仅 24GB 显存的台式机上的表现
|
||||
|
||||
- [摘要](#摘要)
|
||||
- [先决条件](#先决条件)
|
||||
- [基准测试结果](#基准测试结果)
|
||||
- [V0.2](#v02)
|
||||
- [设置](#设置)
|
||||
- [内存占用](#内存占用)
|
||||
- [基准测试结果](#基准测试结果)
|
||||
- [V0.3-Preview](#V0.3-Preview)
|
||||
- [设置](#设置-1)
|
||||
- [内存占用](#内存占用-1)
|
||||
- [基准测试结果](#基准测试结果-1)
|
||||
- [如何运行](#如何运行)
|
||||
- [V0.2 展示](#v02-展示)
|
||||
- [单插槽版本 (32 核心)](#单插槽版本(32 核心))
|
||||
- [双插槽版本 (64 核心)](#双插槽版本(64 核心))
|
||||
- [V0.3 展示](#v03-展示)
|
||||
- [双插槽版本 (64 核心)](#双插槽版本(64 核心)-1)
|
||||
- [一些解释](#一些解释)
|
||||
- [常见问题解答](#常见问题解答)
|
||||
- [R1 不思考](#R1 不返回思考过程)
|
||||
- [更多常见问题解答](#更多常见问题解答)
|
||||
|
||||
# 摘要
|
||||
|
||||
> **2025年2月10日**: 支持在单个(24GB 显存)/多个 GPU 和 382GB 内存上运行 DeepseekR1 和 V3,速度提升高达 3~28 倍。<br>
|
||||
|
||||
嗨,我们是 KTransformers 团队(以前因本地 CPU/GPU 混合推理开源项目 DeepSeek-V2 而闻名)。
|
||||
|
||||
我们听到了您对 DeepSeek-R1/V3 支持的请求——我们很高兴终于可以交付了!很抱歉让您久等了,但我们一直在酝酿一些真正令人惊叹的东西!
|
||||
|
||||
今天,我们自豪地宣布,我们不仅支持 DeepSeek-R1/V3,如下视频所示:
|
||||
|
||||
https://github.com/user-attachments/assets/ebd70bfa-b2c1-4abb-ae3b-296ed38aa285
|
||||
|
||||
</p>
|
||||
|
||||
- **[NEW!!!] 本地 671B DeepSeek-Coder-V3/R1:** 仅使用 14GB 显存和 382GB 内存运行其 Q4_K_M 版本。
|
||||
- 预填充(Prefill)速度 (tokens/s):
|
||||
- KTransformers: 54.21 (32 核心) → 74.362 (双插槽,2×32 核心) → 255.26 (优化的 AMX 基 MoE 内核,仅 V0.3) → 286.55 (选择性使用 6 个专家,仅 V0.3)
|
||||
- 与 llama.cpp 在 2×32 核心下 10.31 tokens/s 相比,速度提升高达 **27.79 倍**
|
||||
- 解码(Decode)速度 (tokens/s):
|
||||
- KTransformers: 8.73 (32 核心) → 11.26 (双插槽, 2×32 核心) → 13.69 (选择性使用 6 个专家,仅 V0.3)
|
||||
- 与 llama.cpp 在 2×32 核心下 4.51 tokens/s 相比,速度提升高达 **3.03 倍**
|
||||
|
||||
我们还提供了即将推出的优化预览,包括英特尔 AMX 加速内核和选择性专家激活方法,这将显著提升性能。通过 V0.3 预览版,我们在预填充方面实现了高达 286 tokens/s 的速度,比本地推理的 llama.cpp **快 28 倍**。二进制发行版现已可用,源代码即将推出!请查看 wheel 包 [此处](https://github.com/kvcache-ai/ktransformers/releases/download/v0.1.4/ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl) 。
|
||||
|
||||
## 先决条件
|
||||
|
||||
我们在以下配置下进行了最佳性能测试(V0.2): <br>
|
||||
CPU: Intel (R) Xeon (R) Gold 6454S 1T 内存 (2 NUMA 节点) <br>
|
||||
GPU: 4090D 24G 显存 <br>
|
||||
内存: 标准 DDR5-4800 服务器内存 (1 TB)
|
||||
|
||||
## 基准测试结果
|
||||
|
||||
### V0.2
|
||||
|
||||
#### 设置
|
||||
|
||||
- Model: DeepseekV3-q4km (int4)<br>
|
||||
- CPU: cpu_model_name: Intel (R) Xeon (R) Gold 6454S,每个插槽 32 核心,2 个插槽,2 个 NUMA 节点
|
||||
- GPU: 4090D 24G 显存
|
||||
- 我们在充分预热后进行测试
|
||||
|
||||
#### 内存占用:
|
||||
|
||||
- 单插槽: 382G 内存,至少 14GB 显存
|
||||
- 双插槽: 1T 内存,至少 14GB 显存
|
||||
|
||||
#### 基准测试结果
|
||||
|
||||
“6 个专家” 情况是 V0.3 预览版中内容
|
||||
|
||||
|
||||
| Prompt<br>(500 tokens) | 双插槽 Ktrans (6 个专家) | 双插槽 Ktrans (8 个专家) | Single socket Ktrans (6 个专家) | Single socket Ktrans (8 个专家) | llama.cpp (8 个专家) |
|
||||
| ----------------------- | ------------------------ | ------------------------ | ------------------------------- | ------------------------------- | -------------------- |
|
||||
| 预填充(Prefill) token/s | 97.32 | 82.94 | 65.14 | 54.21 | 10.31 |
|
||||
| 解码(Decode) token/s | 13.69 | 12.208 | 10.303 | 8.73 | 4.51 |
|
||||
|
||||
**最高加速比在解码方面达到 <u>3.03x</u> 倍,在预填充方面达到 <u>9.44x</u> 倍。**
|
||||
|
||||
### V0.3-Preview
|
||||
|
||||
#### 设置
|
||||
|
||||
- Model: DeepseekV3-BF16 (在线量化为 CPU 的 int8 和 GPU 的 int4)
|
||||
- CPU: cpu_model_name: Intel (R) Xeon (R) Gold 6454S,每个插槽 32 核心,2 个插槽,2 个 NUMA 节点
|
||||
- GPU: (1~4)x 4090D 24G 显存 (更长的 prompt 需要更多显存)
|
||||
|
||||
#### 内存占用:
|
||||
|
||||
- 644GB 内存,至少 14GB 显存
|
||||
|
||||
#### 基准测试结果
|
||||
|
||||
|
||||
| Prompt length | 1K | 2K | 4K | 8K |
|
||||
| --------------------------------- | ------ | ------ | ------ | ------ |
|
||||
| KTrans (8 个专家) Prefill token/s | 185.96 | 255.26 | 252.58 | 195.62 |
|
||||
| KTrans (6 个专家) Prefill token/s | 203.70 | 286.55 | 271.08 | 207.20 |
|
||||
|
||||
**KTrans V0.3 的预填充速度比 KTrans V0.2 快 <u>3.45x</u> 倍,比 llama.cpp 快 <u>27.79x</u> 倍。**
|
||||
**解码速度与 KTrans V0.2(6 个专家版本)相同,因此省略。**
|
||||
|
||||
主要加速来自于
|
||||
|
||||
- 英特尔 AMX 指令集和我们专门设计的缓存友好内存布局
|
||||
- 专家选择策略,根据离线配置文件结果选择更少的专家
|
||||
|
||||
*从我们对 DeepSeekV2、DeepSeekV3 和 DeepSeekR1 的研究中,当我们略微减少推理中的激活专家数量时,输出质量没有变化。但解码和预填充的速度加快了,这令人鼓舞。因此,我们的展示利用了这一发现。*
|
||||
|
||||
## 如何运行
|
||||
|
||||
### 多并发展示
|
||||
|
||||
多并发需要额外编译调度器 c++ 代码
|
||||
|
||||
```shell
|
||||
sudo apt install libtbb-dev libssl-dev libcurl4-openssl-dev libaio1 libaio-dev libfmt-dev
|
||||
sudo apt-get install libgflags-dev zlib1g-dev patchelf
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule update --init --recursive
|
||||
# 如果使用双 numa 版本
|
||||
USE_BALANCE_SERVE=1 USE_NUMA=1 bash ./install.sh
|
||||
# 如果使用单 numa 版本
|
||||
USE_BALANCE_SERVE=1 bash ./install.sh
|
||||
# 启动命令
|
||||
python ktransformers/server/main.py --model_path <your model path> --gguf_path <your gguf path> --cpu_infer 62 --optimize_config_path <inject rule path> --port 10002 --chunk_size 256 --max_new_tokens 1024 --max_batch_size 4 --port 10002 --cache_lens 32768 --backend_type balance_serve
|
||||
```
|
||||
|
||||
`<your model path>` 可以是本地路径,也可以是在线路径,例如 deepseek-ai/DeepSeek-V3。如果在线连接出现问题,可以尝试使用镜像(hf-mirror.com) <br>
|
||||
`<your gguf path>` 也可以是在线路径,但由于其体积较大,我们建议您下载并量化模型(注意这是目录路径)
|
||||
|
||||
`<inject rule path>` 注入规则 yaml 文件地址,我们在 `ktransformers/optimize/optimize_rules/ ` 目录下提供了 `DeepSeek-V3-Chat-serve.yaml` 和 `DeepSeek-V3-Chat-fp8-linear-ggml-experts-serve.yaml` 分别对应 [`DeepSeek-V3/R1-q4km`](https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-Q4_K_M) 和 [`DeepSeek-V3/R1-hybrid`](https://huggingface.co/KVCache-ai/DeepSeek-R1-GGML-FP8-Hybrid/tree/main)
|
||||
|
||||
`--max_new_tokens 1000` 是最大输出 token 长度。如果发现答案被截断,可以增加此数字以获得更长的答案(但要注意内存不足问题,增加此数字会降低生成速度).
|
||||
|
||||
`--chunk_size 256` 引擎单次运行最大 token 个数
|
||||
|
||||
`--cache_lens 32768` 调度器申请 kvcache 的总长度。所有请求共享 32768 个 tokens 对应 kvcache 空间,请求完成后会释放其所占用的 kvcache 空间。
|
||||
|
||||
`--backend_type balance_serve` `balance_serve`是 v0.2.4新增的后端引擎,原本的单并发引擎为`ktransformers`
|
||||
|
||||
`--max_batch_size 4` 引擎单次运行最多处理 4 个请求(prefill + decode),(仅用于`balance_serve`)
|
||||
|
||||
<br>命令 numactl -N 1 -m 1 的目的是避免 NUMA 节点之间的数据传输<br>
|
||||
注意!如果测试 R1 可能会跳过思考。因此,可以添加参数:`--force_think`,这在 [常见问题解答](#常见问题解答) 部分中解释。
|
||||
|
||||
### V0.2 展示
|
||||
|
||||
#### 单插槽版本(32 核心)
|
||||
|
||||
我们的 local_chat 测试命令是:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule init
|
||||
git submodule update
|
||||
numactl -N 1 -m 1 python ./ktransformers/local_chat.py --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 33 --max_new_tokens 1000
|
||||
<当您看到聊天时,按回车键加载文本提示文件>
|
||||
```
|
||||
|
||||
#### 双插槽版本(64 核心)
|
||||
|
||||
在安装之前(使用 install.sh 或 `make dev_install`),请确保设置环境变量 `USE_NUMA=1`,方法是 `export USE_NUMA=1`(如果已经安装,请重新安装并设置此环境变量) <br>
|
||||
我们的 local_chat 测试命令是:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/kvcache-ai/ktransformers.git
|
||||
cd ktransformers
|
||||
git submodule init
|
||||
git submodule update
|
||||
export USE_NUMA=1
|
||||
make dev_install # or sh ./install.sh
|
||||
python ./ktransformers/local_chat.py --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 65 --max_new_tokens 1000
|
||||
<当您看到聊天时,按回车键加载文本提示文件>
|
||||
```
|
||||
|
||||
参数的含义相同。但因为我们使用双插槽,所以将 cpu_infer 设置为 65。
|
||||
|
||||
### V0.3 展示
|
||||
|
||||
#### 双插槽版本(64 核心)
|
||||
|
||||
我们的 local_chat 测试命令是:
|
||||
|
||||
```shell
|
||||
wget https://github.com/kvcache-ai/ktransformers/releases/download/v0.1.4/ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl
|
||||
pip install ./ktransformers-0.3.0rc0+cu126torch26fancy-cp311-cp311-linux_x86_64.whl
|
||||
python -m ktransformers.local_chat --model_path <your model path> --gguf_path <your gguf path> --prompt_file <your prompt txt file> --cpu_infer 65 --max_new_tokens 1000
|
||||
<当您看到聊天时,按回车键加载文本提示文件>
|
||||
```
|
||||
|
||||
参数的含义与 V0.2 相同。但因为我们使用双插槽,所以将 cpu_infer 设置为 65。
|
||||
|
||||
## 一些解释
|
||||
|
||||
1. 我们还想进一步利用 Xeon Gold CPU 上的两个 NUMA 节点。为了避免节点之间的数据传输成本,我们在两个节点上 "copy" 了关键矩阵,这会增加内存占用,但会加速预填充和解码过程。但这种方法占用大量内存,加载权重时速度较慢,因此加载时请耐心等待并监控内存使用情况。我们计划优化这一巨大的内存开销。敬请期待。
|
||||
2. 命令参数 `--cpu_infer 65` 指定使用多少核心(超过物理核心数量是可以的,但并不是越多越好。根据实际核心数量适当降低此值)。<br>
|
||||
3. 为什么使用 CPU/GPU 混合推理?
|
||||
DeepSeek 的 MLA 操作符计算密集。虽然全部在 CPU 上运行是可行的,但将繁重的计算任务卸载到 GPU 上能带来巨大的性能提升。
|
||||
4. 加速来自哪里?
|
||||
|
||||
- 专家卸载:与传统的基于层或 KVCache 卸载(如 llama.cpp 中的)不同,我们将专家计算卸载到 CPU,将 MLA/KVCache 卸载到 GPU,与 DeepSeek 的架构完美对齐,实现最佳效率。
|
||||
- 英特尔 AMX 优化 – 我们的 AMX 加速内核经过精心调优,运行速度是现有 llama.cpp 实现的数倍。我们计划在清理后开源此内核,并考虑向 llama.cpp 上游贡献代码。
|
||||
5. 为什么选择英特尔 CPU?
|
||||
英特尔目前是唯一支持 AMX 类似指令的 CPU 供应商,与仅支持 AVX 的替代方案相比,性能显著更好。
|
||||
|
||||
## 常见问题解答
|
||||
|
||||
### R1 不返回思考过程
|
||||
|
||||
注意!如果测试 R1 可能会跳过思考。因此,可以添加参数:`--force_think true`。详细信息在 [常见问题解答](./FAQ.md) 部分中。 <br>
|
||||
|
||||
## 问题
|
||||
|
||||
* 修复服务器集成功能以实现网络API访问支持
|
||||
* 修复本地聊天功能仅支持单行提示输入的问题(目前输入换行符(\n)即开始生成提示)
|
||||
|
||||
### 更多常见问题解答
|
||||
|
||||
[详见](./FAQ.md)
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
# API
|
||||
|
||||
|
||||
- [OpenAI ChatCompletion](#openai-chatcompletion)
|
||||
- [Ollama ChatCompletion](#ollama-chatcompletion)
|
||||
- [OpenAI Assistant](#openai-assistant)
|
||||
|
||||
|
||||
## OpenAI ChatCompletion
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
```
|
||||
根据选定的模型生成回复。
|
||||
|
||||
### 参数
|
||||
|
||||
|
||||
- `messages`:一个 `message` 的数组所有的历史消息。`message`:表示用户(user)或者模型(assistant)的消息。`message`包含:
|
||||
|
||||
- `role`: 取值`user`或`assistant`,代表这个 message 的创建者。
|
||||
- `content`: 用户或者模型的消息。
|
||||
|
||||
- `model`:选定的模型名
|
||||
- `stream`:取值 true 或者 false。表示是否使用流式返回。如果为 true,则以 http 的 event stream 的方式返回模型推理结果。
|
||||
|
||||
### 响应
|
||||
|
||||
- 流式返回:一个 event stream,每个 event 含有一个`chat.completion.chunk`。`chunk.choices[0].delta.content`是每次模型返回的增量输出。
|
||||
- 非流式返回:还未支持。
|
||||
|
||||
### 例子
|
||||
|
||||
```bash
|
||||
curl -X 'POST' \
|
||||
'http://localhost:9112/v1/chat/completions' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"messages": [
|
||||
{
|
||||
"content": "tell a joke",
|
||||
"role": "user"
|
||||
}
|
||||
],
|
||||
"model": "Meta-Llama-3-8B-Instruct",
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
```bash
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"Why ","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"couldn't ","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
...
|
||||
|
||||
data:{"id":"c30445e8-1061-4149-a101-39b8222e79e1","object":"chat.completion.chunk","created":1720511671,"model":"not implmented","system_fingerprint":"not implmented","usage":null,"choices":[{"index":0,"delta":{"content":"two-tired!","role":"assistant","name":null},"logprobs":null,"finish_reason":null}]}
|
||||
|
||||
event: done
|
||||
data: [DONE]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Ollama ChatCompletion
|
||||
|
||||
```bash
|
||||
POST /api/generate
|
||||
```
|
||||
|
||||
根据选定的模型生成回复。
|
||||
|
||||
### 参数
|
||||
|
||||
|
||||
- `prompt`:一个字符串,代表输入的 prompt。
|
||||
- `model`:选定的模型名
|
||||
- `stream`:取值 true 或者 false。表示是否使用流式返回。如果为 true,则以 http 的 event stream 的方式返回模型推理结果。
|
||||
|
||||
### 响应
|
||||
|
||||
- 流式返回:一个流式的 json 返回,每行是一个 json。
|
||||
- `response`:模型补全的增量结果。
|
||||
- `done`:是否推理结束。
|
||||
|
||||
- 非流式返回:还未支持。
|
||||
|
||||
### 例子
|
||||
|
||||
```bash
|
||||
curl -X 'POST' \
|
||||
'http://localhost:9112/api/generate' \
|
||||
-H 'accept: application/json' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"model": "Meta-Llama-3-8B-Instruct",
|
||||
"prompt": "tell me a joke",
|
||||
"stream": true
|
||||
}'
|
||||
```
|
||||
|
||||
```bash
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:11.686513","response":"I'll ","done":false}
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:11.729214","response":"give ","done":false}
|
||||
|
||||
...
|
||||
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:33.955475","response":"for","done":false}
|
||||
{"model":"Meta-Llama-3-8B-Instruct","created_at":"2024-07-09 08:13:33.956795","response":"","done":true}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 181 KiB |
|
|
@ -1,41 +0,0 @@
|
|||
# 后端服务(Server)
|
||||
Server 将 ktransformers 的快速异构推理能力通过 API 提供给外界调用。
|
||||
|
||||
<img src="server-arch.png" height="600" alt="Server架构">
|
||||
|
||||
## API
|
||||
|
||||
Server 通过 RESTful API 对外提供模型推理服务,提供 ChatCompletion 和 Assistant 两种调用方式。
|
||||
|
||||
- ChatCompletion 接口要求用户一次提供所有的历史对话,然后返回模型的回复。AI 服务提供商(例如[OpenAI](https://platform.openai.com/docs/api-reference/chat/create) )和本地推理框架(例如[Ollama](https://github.com/ollama/ollama/blob/main/docs/api.md) )都提供 ChatCompletion 接口。为了兼容 OpenAI 和 Ollama,Server 分别提供和它们一致的 API 接口。因此,当前使用 OpenAI 和 Ollama 的应用可以无缝切换到我们的 Server。例如: [如何使用 Tabby 和 ktransformers 在本地利用 236B 的大模型做代码补全?](tabby.md)。
|
||||
- Assistant 适用于应用需要复用一系列资源并调用模型的场景。例如,在教育应用场景中,应用开发者可以创建一个名为二年级数学老师的 Assistant,并设置初始prompt(“你是一个有经验的的二年级数学老师...”),上传相关的资料(二年级数学教材)。创建 Assistant 后,应用需要创建一个 Thread 来存储用户和模型的对话消息(Message)。调用模型时,应用需要创建一个 Run 来获得 Assistant 的回复。相对于 ChatCompletion,实现了 Assistant 的 Server 代替应用实现了对话背景复用和多轮对话,使得复杂场景下的模型的调用更加方便。 [OpenAI Assistant API](https://platform.openai.com/docs/api-reference/assistants/createAssistant) 提出了这样的 Assistant 接口,而 Server 也提供和它一致的 API 。
|
||||
|
||||
这些 API 定义在`server/api`中,它们的具体使用请见[这里](api.md)。
|
||||
|
||||
|
||||
## 对接模型推理框架
|
||||
|
||||
Server 通过 ktransformers 调用模型并进行推理。Server 也支持其他的推理框架,例如已经支持的 [transformers](https://huggingface.co/docs/transformers/index) ,并计划支持 [exllamav2](https://github.com/turboderp/exllamav2)。这些功能在`server/backend` 中实现。
|
||||
|
||||
Server 将模型推理框架的推理功能抽象成一个基类`BackendInterfaceBase`。这个基类包含一个函数:inference。它的输入是是历史的对话信息 messages,输出是模型返回的文字结果。inference 函数采用 async generator 的设计,这使得 Server 可以流式地返回模型的回复。
|
||||
|
||||
```python
|
||||
class BackendInterfaceBase:
|
||||
async def inference(self, messages, **kwargs)->AsyncIterator[str]:
|
||||
...
|
||||
```
|
||||
|
||||
这个 inference 函数,因为它的输入和输出分别是历史对话和模型回复,所以它自然地实现了 ChatCompletion 的功能。因此 ChatCompletion API 可以直接调用inference 函数完成模型推理。
|
||||
|
||||
而 Assistant 则比 ChatCompletion 复杂许多,需要 Server 存储 Assistant 的相关状态,并以合适的方式调用 inference 函数。Server 在数据库中维护了一套 Assistant 逻辑,存储应用创建的 Assistant,Thread 和 Message。在内存中,Server 为每个 Thread 维护一个 `ThreadContext`,集合每个Thread 相关的 Assistant 等信息。当用户发出新的 Message 时,Server 调用 ThreadContext 的get_local_messages函数,获得 messages,并调用 inference 函数获得推理结果。
|
||||
|
||||
```python
|
||||
class MyThreadContext(ThreadContext):
|
||||
def get_local_messages(self):
|
||||
...
|
||||
```
|
||||
|
||||
由于不同的模型推理框架有着不同的历史对话输入格式,所以 `ThreadContext` 和 `BackendInterface` 需要成对地使用。Server 除了自己的 ktransformers 之外,还支持 transformers。如果要对接其他的模型推理框架,可以参考在 [transformers.py](https://github.com/kvcache-ai/ktransformers-dev/blob/main/ktransformers/server/backend/interfaces/transformers.py) 中`TransformersInterface`和`TransformersThreadContext`的实现。
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# 如何使用 Tabby 和 ktransformers 在本地利用 236B 的大模型做代码补全?
|
||||
|
||||
[Tabby](https://tabby.tabbyml.com/docs/welcome/) 是一个开源的代码助手,用户可以手动配置后端使用的框架及模型,并在多个 IDE/编辑器 上使用,例如 VSCode 和 InteliJ。因为 Tabby 在框架侧可以对接到 Ollama,并且 ktransformers server 提供和 Ollama 一致的 API 接口,所以我们可以将 Tabby 对接到 ktransformers server。并在代码补全的场景中体验到 ktransformers 快速的异构推理。
|
||||
|
||||
1. 启动 ktransformers。
|
||||
```bash
|
||||
./ktransformers --port 9112
|
||||
```
|
||||
2. 安装 Tabby:按照 Tabby 的官方教程在带有英伟达 GPU 的 Linux 服务器或者 Windows PC 上[安装 Tabby](https://tabby.tabbyml.com/docs/quick-start/installation/linux/)。
|
||||
3. 配置 Tabby:创建`~/.tabby/config.toml`,并加入以下配置。
|
||||
```toml
|
||||
[model.completion.http]
|
||||
kind = "ollama/completion"
|
||||
api_endpoint = "http://127.0.0.1:9112/"
|
||||
model_name = "DeepSeek-Coder-V2-Instruct"
|
||||
prompt_template = "<|fim▁begin|>{prefix}<|fim▁hole|>{suffix}<|fim▁end|>" # Prompt Template
|
||||
```
|
||||
|
||||
在这个配置中,`kind` 指明 ktransformers 使用 Ollama 的标准 API 为 Tabby 提供服务;`api_endpoint` 与 ktransforer 启动时绑定的接口保持一致;`model_name` 设置为 ktransformers 使用的模型,这里使用 `DeepSeek-Coder-V2-Instruct` 作为后台推理的模型;`prompt_template` 是模型的提示词模板,针对不同的模型,使用相对应的模版才能正常使用模型 Fill In the Middle 的功能。
|
||||
在这里演示的是 Tabby 使用 Ollama API 提供 Completion 功能的相关配置,有关 Tabby 其他可选功能的配置信息请参照[这里](https://tabby.tabbyml.com/docs/administration/model/)。
|
||||
|
||||
|
||||
4. 启动 Tabby 服务:`./tabby serve`。
|
||||
<img src="run-tabby.png" alt="image-20240709112329577" style="zoom:50%;" />
|
||||
|
||||
启动之后,期望会在 ktransformers 的命令行界面看到对 `/api/tags` 接口的访问(在 Tabby 新版本 v0.13.0 中变为对 `/api/show/` 接口的访问)。
|
||||
<img src="visit-api-tags.png" alt="image-20240709111648215" style="zoom:67%;" />
|
||||
|
||||
6. 注册 Tabby 账户,获取 Token:在启动 Tabby 服务后,在浏览器中打开相应的链接(如上图的 0.0.0.0:8080),并参照[教程](https://tabby.tabbyml.com/docs/quick-start/register-account/) 创建用户并获取 Token。
|
||||
|
||||
7. 启动 VScode 安装 Tabby 拓展插件,并在相关提示下,使用上一步获得的 Token 连接 Tabby Server,参照[这里](https://tabby.tabbyml.com/docs/extensions/installation/vscode/)。
|
||||
|
||||
8. 打开任意代码文件,体验 ktransformers 的快速异构推理。
|
||||
|
||||
|
Before Width: | Height: | Size: 57 KiB |
|
|
@ -1,32 +0,0 @@
|
|||
# Start with website
|
||||
|
||||
This document provides the necessary steps to set up and run the web service for this project.
|
||||
|
||||
## 1. Starting the Web Service
|
||||
|
||||
### 1.1. Compiling the Web Code
|
||||
|
||||
Before you can compile the web code, make sure you have installed [Node.js](https://nodejs.org) version 18.3 or higher
|
||||
|
||||
Once npm is installed, navigate to the `ktransformers/website` directory:
|
||||
|
||||
```bash
|
||||
cd ktransformers/website
|
||||
```
|
||||
|
||||
Next, install the Vue CLI with the following command:
|
||||
|
||||
```bash
|
||||
npm install @vue/cli
|
||||
```
|
||||
|
||||
Now you can build the project:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
Finally you can build ktransformers with website:
|
||||
```
|
||||
cd ../../
|
||||
pip install .
|
||||
```
|
||||
BIN
doc/assets/image-20250801165752484.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
doc/assets/image-20250801174517784.png
Normal file
|
After Width: | Height: | Size: 652 KiB |
BIN
doc/assets/image-20250801174623919.png
Normal file
|
After Width: | Height: | Size: 175 KiB |
BIN
doc/assets/image-20250911184023795.png
Normal file
|
After Width: | Height: | Size: 605 KiB |
BIN
doc/assets/image-20250911184455749.png
Normal file
|
After Width: | Height: | Size: 201 KiB |
BIN
doc/assets/image-20251011010558909.png
Normal file
|
After Width: | Height: | Size: 224 KiB |
BIN
doc/assets/image-20251016171526210.png
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
doc/assets/image-20251016171537997.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
doc/assets/image-20251016175046882.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
doc/assets/image-20251016175848143.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
doc/assets/image-20251016182810716.png
Normal file
|
After Width: | Height: | Size: 781 KiB |
BIN
doc/assets/image-20251016182920722.png
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
BIN
doc/assets/image-20251016182942726.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
doc/assets/image-compare_model.png
Normal file
|
After Width: | Height: | Size: 3.1 MiB |
BIN
doc/assets/演示文稿1_01.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
doc/assets/风格化数据集模型输出对比_01.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
294
doc/en/KTransformers Fine-Tuning -- User Guide.md
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
- [KTransformers Fine-Tuning × LLaMA-Factory Integration – User Guide](#ktransformers-fine-tuning-x-llama-factory-integration-–-user-guide)
|
||||
- [Introduction](#introduction)
|
||||
|
||||
- [Fine-Tuning Results (Examples)](#fine-tuning-results-examples)
|
||||
- [Stylized Dialogue (CatGirl tone)](#stylized-dialogue-catgirl-tone)
|
||||
- [Benchmarks](#benchmarks)
|
||||
- [Translational-Style dataset](#translational-style-dataset)
|
||||
- [AfriMed-QA (short answer)](#afrimed-qa-short-answer)
|
||||
- [AfriMed-QA (multiple choice)](#afrimed-qa-multiple-choice)
|
||||
|
||||
- [Quick to Start](#quick-to-start)
|
||||
- [Environment Setup](#environment-setup)
|
||||
- [Core Feature 1: Use KTransformers backend to fine-tune ultra-large MoE models](#core-feature-1-use-ktransformers-backend-to-fine-tune-ultra-large-moe-models)
|
||||
- [Core Feature 2: Chat with the fine-tuned model (base + LoRA adapter)](#core-feature-2-chat-with-the-fine-tuned-model-base--lora-adapter)
|
||||
- [Core Feature 3: Batch inference + metrics (base + LoRA adapter)](#core-feature-3-batch-inference--metrics-base--lora-adapter)
|
||||
|
||||
- [KT Fine-Tuning Speed (User-Side View)](#kt-fine-tuning-speed-user-side-view)
|
||||
- [End-to-End Performance](#end-to-end-performance)
|
||||
- [GPU/CPU Memory Footprint](#gpucpu-memory-footprint)
|
||||
|
||||
- [Conclusion](#conclusion)
|
||||
|
||||
|
||||
# KTransformers Fine-Tuning × LLaMA-Factory Integration – User Guide
|
||||
|
||||
**MadSys Lab, KVCache-AI Team, Approaching AI, LLaMA-Factory Team**
|
||||
|
||||
## Introduction
|
||||
|
||||
From **DeepSeek-V3/R1** to **Qwen3-MoE** and **Kimi-K2**, each wave of open-sourced large models brings leaps in performance and scale. However, many researchers and developers are constrained by expensive GPUs and models with tens or even hundreds of billions of parameters, making it **hard to fine-tune very large models under limited resources**. To bridge this gap, we propose a practical approach: combining **KTransformers** with **LLaMA-Factory**. With just **2–4 RTX 4090s** and a high-memory CPU, you can fine-tune ultra-large MoE models like DeepSeek-671B.
|
||||
|
||||
Our goal is to give resource-constrained researchers a **local path to explore fine-tuning ultra-large models**, and also a fast way to customize smaller models (e.g., 14B/30B) for specific scenarios. We validate the setup using **stylized dialogue**, **Westernized translation tone**, and **medical Q&A** as representative tasks, showing that **personalized adaptation can be achieved within hours**.
|
||||
|
||||
As shown below, LLaMA-Factory is the unified orchestration/configuration layer for the whole fine-tuning workflow—handling data, training scheduling, LoRA injection, and inference interfaces. **KTransformers** acts as a pluggable high-performance backend that takes over core operators like Attention/MoE under the same training configs, enabling efficient **GPU+CPU heterogeneous cooperation**.
|
||||
|
||||

|
||||
|
||||
Within LLaMA-Factory, we compared LoRA fine-tuning with **HuggingFace**, **Unsloth**, and **KTransformers** backends. KTransformers is the **only workable 4090-class solution** for ultra-large MoE models (e.g., 671B) and also delivers higher throughput and lower GPU memory on smaller MoE models (e.g., DeepSeek-14B).
|
||||
|
||||
| Under LoRA (BF16) + [NekoQA-10K stylized dialogue](https://github.com/mindsRiverPonder/LLM-practice) | HuggingFace Backend | Unsloth Backend | KTransformers Backend |
|
||||
| ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------ | --------------------- |
|
||||
| [14B-DeepSeekV2-Lite] LoRA fine-tuning throughput | 303.58 token/s | 455.37 token/s | 530.38 token/s |
|
||||
| [14B-DeepSeekV2-Lite] GPU memory | 32.12 GB | 9.64 GB | 6.08 GB |
|
||||
| [671B-DeepSeekV3] LoRA fine-tuning throughput | <font color='red'>Too Huge to run</font> | <font color='red'>NOT SUPPORT</font> | 40.35 token/s |
|
||||
| [671B-DeepSeekV3] GPU memory (sum across GPUs) | theoretical 1400 GB † | <font color='red'>NOT SUPPORT</font> | 70 GB † |
|
||||
|
||||
† **1400 GB** is a **theoretical** FP16 full-parameter resident footprint (not runnable). **70 GB** is the **measured peak** with KT strategy (Attention on GPU + layered MoE offload).
|
||||
|
||||

|
||||
|
||||
### Fine-Tuning Results (Examples)
|
||||
|
||||
#### Stylized Dialogue (CatGirl tone)
|
||||
|
||||
Dataset: [NekoQA-10K](https://zhuanlan.zhihu.com/p/1934983798233231689). Goal: improve style consistency and recognizability.
|
||||
|
||||
The figure compares responses from the base vs. fine-tuned models. The fine-tuned model maintains the target tone and address terms more consistently (red boxes), validating the effectiveness of **style-transfer fine-tuning**.
|
||||
|
||||

|
||||
|
||||
#### Benchmarks
|
||||
|
||||
We use:
|
||||
|
||||
(1) [Translational-Style-ChatLLM](https://github.com/Benson114/Translational-Style-ChatLLM), which asks for an exaggerated, Westernized translation tone—clear, stylized customization.
|
||||
|
||||
(2) [AfriMed-QA](https://aclanthology.org/2025.acl-long.96/) (ACL 2025), a medical dataset for African contexts with strong domain specificity, including multiple-choice and short-answer sub-tasks—well-suited for vertical fine-tuning evaluation.
|
||||
|
||||
The tables show metrics before vs. after LoRA fine-tuning. We observe **large improvements** across metrics, verifying fine-tuning effectiveness:
|
||||
|
||||
| Translational-Style dataset | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.41** | **22.44** | **15.42** | **11.18** | **42.03** | **18.38** | **33.10** |
|
||||
| V3 base (no LoRA) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
|
||||
| **KT-LoRA fine-tuned V3** | **37.02** | **23.70** | **16.21** | **11.49** | **43.43** | **18.96** | **34.54** |
|
||||
|
||||
| AfriMed-QA (short answer) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.90** | **27.63** | **22.99** | **19.15** | **35.25** | **17.50** | **28.44** |
|
||||
| V3 base (no LoRA) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
|
||||
| **KT-LoRA fine-tuned V3** | **42.42** | **34.12** | **28.95** | **24.54** | **41.97** | **22.37** | **33.28** |
|
||||
|
||||
| AfriMed-QA (multiple choice) | Accuracy |
|
||||
| ------------------------------ | ---------- |
|
||||
| V2-Lite (no LoRA) | 0.0645 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **0.4812** |
|
||||
| V3 base (no LoRA) | 0.5833 |
|
||||
| **KT-LoRA fine-tuned V3** | **0.7930** |
|
||||
|
||||
Even for ultra-large MoE models, **KTransformers-backed fine-tuning** achieves strong task performance quickly.
|
||||
|
||||
|
||||
|
||||
## Quick to Start
|
||||
|
||||
This section shows how to install and use **LLaMA-Factory + KTransformers** for fine-tuning and inference:
|
||||
|
||||
- Environment setup
|
||||
- Fine-tune ultra-large MoE models with KTransformers backend
|
||||
- Load the fine-tuned model (base + LoRA adapter) for chat/inference
|
||||
- Batch inference and metric evaluation
|
||||
|
||||
### Environment Setup
|
||||
|
||||
According to the following example, install both the **KTransformers** and **LLaMA-Factory** environments simultaneously.
|
||||
This time, to simplify the installation process of KTransformers, we have specially packaged a wheel file to avoid local compilation.
|
||||
The detailed installation steps are as follows:
|
||||
(Note: Make sure your local **Python version**, **Torch version**, **CUDA version**, and the **KTransformers wheel filename** correspond correctly.)
|
||||
|
||||
```shell
|
||||
# 1. Create a conda environment
|
||||
conda create -n Kllama python=3.10 # choose from : [3.10, 3.11, 3.12, 3.13]
|
||||
conda install -y -c conda-forge libstdcxx-ng gcc_impl_linux-64
|
||||
conda install -y -c nvidia/label/cuda-11.8.0 cuda-runtime
|
||||
|
||||
# 2. Install the LLaMA-Factory environment
|
||||
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
|
||||
cd LLaMA-Factory
|
||||
pip install -e ".[torch,metrics]" --no-build-isolation
|
||||
|
||||
# 3. Install the KTransformers wheel that matches your Torch and Python versions (Note: The CUDA version can differ from that in the wheel filename.)
|
||||
pip install ktransformers-0.4.1+cu128torch28fancy-cp310-cp310-linux_x86_64.whl
|
||||
|
||||
# 4. Install flash-attention, download the corresponding file based on your Python and Torch versions from: https://github.com/Dao-AILab/flash-attention/releases
|
||||
pip install https://github.com/Dao-AILab/flash-attention/releases/download/v2.8.3/flash_attn-2.8.3+cu12torch2.8cxx11abiTRUE-cp310-cp310-linux_x86_64.whl
|
||||
# abi=True/False can find from below
|
||||
# import torch
|
||||
# print(torch._C._GLIBCXX_USE_CXX11_ABI)
|
||||
|
||||
# 5. (Optional) If you want to use flash_infer (otherwise it defaults to triton)
|
||||
git clone https://github.com/kvcache-ai/custom_flashinfer.git
|
||||
pip install custom_flashinfer/
|
||||
```
|
||||
|
||||
**Usage tip:** In LLaMA-Factory YAML, set `use_kt: true` and pick a `kt_optimize_rule` file to have KTransformers handle the core compute. The features below show typical configs.
|
||||
|
||||
### Core Feature 1: Use KTransformers backend to fine-tune ultra-large MoE models
|
||||
|
||||
Run the command: `USE_KT=1 llamafactory-cli train examples/train_lora/deepseek3_lora_sft_kt.yaml`.
|
||||
|
||||
Note: You **must** provide a **BF16** model. DeepSeek-V3-671B is released in FP8 by default; convert with [DeepSeek-V3/inference/fp8_cast_bf16.py](https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/fp8_cast_bf16.py).
|
||||
|
||||
```yaml
|
||||
### model
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
trust_remote_code: true
|
||||
|
||||
### method
|
||||
stage: sft
|
||||
do_train: true
|
||||
finetuning_type: lora
|
||||
lora_rank: 8
|
||||
lora_target: all
|
||||
|
||||
### dataset
|
||||
dataset: identity
|
||||
template: deepseek
|
||||
cutoff_len: 2048
|
||||
max_samples: 100000
|
||||
overwrite_cache: true
|
||||
preprocessing_num_workers: 16
|
||||
dataloader_num_workers: 4
|
||||
|
||||
### output
|
||||
output_dir: saves/Kllama_deepseekV3
|
||||
logging_steps: 10
|
||||
save_steps: 500
|
||||
plot_loss: true
|
||||
overwrite_output_dir: true
|
||||
save_only_model: false
|
||||
report_to: none # choices: [none, wandb, tensorboard, swanlab, mlflow]
|
||||
|
||||
### train
|
||||
per_device_train_batch_size: 1
|
||||
gradient_accumulation_steps: 8
|
||||
learning_rate: 1.0e-4
|
||||
num_train_epochs: 3.0
|
||||
lr_scheduler_type: cosine
|
||||
warmup_ratio: 0.1
|
||||
bf16: true
|
||||
ddp_timeout: 180000000
|
||||
resume_from_checkpoint: null
|
||||
|
||||
### ktransformers
|
||||
use_kt: true # use KTransformers as LoRA sft backend
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
`kt_optimize_rule` controls **placement strategy**. See also [ktransformers/optimize_rules](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/optimize/optimize_rules). Naming hints (`*` = wildcard):
|
||||
|
||||
| Pattern | Meaning |
|
||||
| -------------------------------------------- | ----------------------------------------------------- |
|
||||
| DeepSeek-V2-Lite-Chat-* / DeepSeek-V3-Chat-* | Target model variants |
|
||||
| *-sft-* | Strategy for fine-tuning; others are for inference |
|
||||
| *-amx-* | Use AMX on CPU; otherwise use **llamafile** |
|
||||
| *-multi-gpu-X* | Model parallel on X GPUs (X omitted → default 2 GPUs) |
|
||||
|
||||
Example: `DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml` = V3-Chat fine-tuning with AMX and 2-GPU model parallel.
|
||||
|
||||
We recommend **AMX acceleration** where available (`lscpu | grep amx`). AMX supports BF16/INT8. Example:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert parallelism
|
||||
kwargs:
|
||||
prefill_device: "cpu"
|
||||
prefill_op: "KExpertsTorch"
|
||||
generate_device: "cpu"
|
||||
generate_op: "KSFTExpertsCPU"
|
||||
out_device: "cuda"
|
||||
backend: "AMXInt8" # or "AMXBF16" or "llamafile" (default)
|
||||
```
|
||||
|
||||
Outputs go to `output_dir` in safetensors format plus adapter metadata for later loading.
|
||||
|
||||

|
||||
|
||||
### Core Feature 2: Chat with the fine-tuned model (base + LoRA adapter)
|
||||
|
||||
Run the command: `llamafactory-cli chat examples/inference/deepseek3_lora_sft_kt.yaml`.
|
||||
|
||||
Use the safetensors adapter trained with KT for inference.
|
||||
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
use_kt: true # use KTransformers as LoRA sft backend to inference
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
We also support **GGUF** adapters: for safetensors, set the **directory**; for GGUF, set the **file path** in `adapter_name_or_path`.
|
||||
|
||||
During loading, LLaMA-Factory maps layer names to KT’s naming. You’ll see logs like `Loaded adapter weight: XXX -> XXX`:
|
||||
|
||||

|
||||
|
||||
### Core Feature 3: Batch inference + metrics (base + LoRA adapter)
|
||||
|
||||
Run the command: `API_PORT=8000 llamafactory-cli api examples/inference/deepseek3_lora_sft_kt.yaml`.
|
||||
Invoke the KT fine-tuned adapter to provide the API; the usage logic of other APIs is consistent with the native LLaMA-Factory approach.
|
||||
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
use_kt: true # use KTransformers as LoRA sft backend to inference
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
|
||||
|
||||
## KT Fine-Tuning Speed (User-Side View)
|
||||
|
||||
### End-to-End Performance
|
||||
|
||||
**Definitions**
|
||||
|
||||
- `step_time`: wall-clock time for a full optimization step (tensor movement + Attention + MoE + other compute).
|
||||
- `tokens_per_step = GAS × qlen`; `token/s = tokens_per_step / step_time`.
|
||||
|
||||
**Settings:** `GAS=16`, `qlen=512` (→ `tokens_per_step = 8192`); LoRA (`r=8, alpha=32, dropout=0.1`); **AMX** enabled; GPU: RTX 4090, CPU: Intel Xeon Platinum 8488C.
|
||||
|
||||
**Measured**
|
||||
|
||||
- **DeepSeek-V3-671B:** `step_time = 203 s` → `token/s ≈ 8192 / 203 ≈ 40.35`
|
||||
- **DeepSeek-V2-Lite-14B:** `step_time = 36 s` → `token/s ≈ 8192 / 36 ≈ 227.6`
|
||||
|
||||
### GPU/CPU Memory Footprint
|
||||
|
||||
- DeepSeek-V3 (671B; 61 layers with 58 MoE): ~**70 GB** total GPU memory (multi-GPU), ~**1.2–1.3 TB** host memory.
|
||||
- DeepSeek-V2-Lite (14B; 27 layers with 26 MoE): ~**5.5 GB** GPU memory, ~**150 GB** host memory.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By integrating **KTransformers LoRA fine-tuning** into **LLaMA-Factory**, we provide a practical guide for efficient training and deployment of MoE LLMs. KT brings cutting-edge optimizations (DeepSeek/Qwen/Kimi support with AMX-accelerated kernels), and LoRA enables customization under very low GPU memory. LLaMA-Factory offers a friendly, unified interface.
|
||||
|
||||
This integration (akin to Unsloth-style speedups) means even models with tens to hundreds of billions of parameters can be fine-tuned and deployed with low latency on commodity hardware. You get **memory savings, speed-ups, and usability** together. We encourage you to try LLaMA-Factory + KT for your next MoE project and follow this guide. Feedback is welcome!
|
||||
221
doc/en/KTransformers Fine-Tuning--Developer Technical Notes.md
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
- [KTransformers Fine-Tuning × LLaMA-Factory Integration – Developer Technical Notes](#ktransformers-fine-tuning-x-llama-factory-integration-–-developer-technical-notes)
|
||||
- [Introduction](#introduction)
|
||||
|
||||
- [Overall View of the KT Fine-Tuning Framework](#overall-view-of-the-kt-fine-tuning-framework)
|
||||
- [Attention (LoRA + KT coexist)](#attention-lora--kt-coexist)
|
||||
- [MoE (operator encapsulation + backward)](#moe-operator-encapsulation--backward)
|
||||
- [Encapsulation](#encapsulation)
|
||||
- [Backward (CPU)](#backward-cpu)
|
||||
- [Multi-GPU Loading/Training: Placement strategy instead of DataParallel](#multi-gpu-loadingtraining-placement-strategy-instead-of-dataparallel)
|
||||
|
||||
- [KT-LoRA Fine-Tuning Evaluation](#kt-lora-fine-tuning-evaluation)
|
||||
- [Setup](#setup)
|
||||
- [Results](#results)
|
||||
- [Stylized Dialogue (CatGirl tone)](#stylized-dialogue-catgirl-tone)
|
||||
- [Translational-Style benchmark (generative)](#translational-style-benchmark-generative)
|
||||
- [Medical Vertical Benchmark (AfriMed-SAQ/MCQ)](#medical-vertical-benchmark-afrimed-saqmcq)
|
||||
- [Limitations](#limitations)
|
||||
|
||||
- [Speed Tests](#speed-tests)
|
||||
- [End-to-End Performance](#end-to-end-performance)
|
||||
- [MoE Compute (DeepSeek-V3-671B)](#moe-compute-deepseek-v3-671b)
|
||||
- [Memory Footprint](#memory-footprint)
|
||||
|
||||
- [Conclusion](#conclusion)
|
||||
|
||||
|
||||
# KTransformers Fine-Tuning × LLaMA-Factory Integration – Developer Technical Notes
|
||||
|
||||
**MadSys Lab, KVCache-AI Team, Approaching AI, LLaMA-Factory Team**
|
||||
|
||||
## Introduction
|
||||
|
||||
Recent open-source LLMs—from DeepSeek-V3/R1 to Qwen-MoE and Kimi-K2—have surged in performance and scale. Yet due to **compute and memory constraints**, it is difficult for typical researchers to fine-tune trillion-parameter-class models. We therefore integrate **KTransformers** with **LLaMA-Factory** so that, with **2–4 RTX 4090 GPUs** and sufficient CPU memory, one can fine-tune ultra-large Mixture-of-Experts (MoE) models such as DeepSeek-671B.
|
||||
|
||||
This architecture bridges resource gaps, enabling **local fine-tuning of ultra-large models**, while also supporting **efficient scenario customization** at 14B/30B scales. We validate on stylized dialogue, Westernized translation tone, and medical Q&A, achieving rapid adaptation within hours.
|
||||
|
||||
Architecturally, LLaMA-Factory orchestrates data/config/training, LoRA insertion, and inference; KTransformers is a pluggable, high-performance operator backend that takes over Attention and MoE under the same training code, enabling **GPU+CPU heterogeneity** to accelerate training and reduce GPU memory.
|
||||
|
||||

|
||||
|
||||
We evaluated LoRA fine-tuning with HuggingFace default, Unsloth, and KTransformers backends (same settings and data). **KTransformers** is currently the only solution feasible on **2–4×24GB 4090s** for **671B-scale MoE**, and also shows higher throughput and lower GPU memory for 14B MoEs.
|
||||
|
||||
| Under LoRA (BF16) + [NekoQA-10K stylized dialogue](https://github.com/mindsRiverPonder/LLM-practice) | HuggingFace Backend | Unsloth Backend | KTransformers Backend |
|
||||
| ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------ | --------------------- |
|
||||
| [14B-DeepSeekV2-Lite] LoRA fine-tuning throughput | 303.58 token/s | 455.37 token/s | 530.38 token/s |
|
||||
| [14B-DeepSeekV2-Lite] GPU memory | 32.12 GB | 9.64 GB | 6.08 GB |
|
||||
| [671B-DeepSeekV3] LoRA fine-tuning throughput | <font color='red'>Too Huge to run</font> | <font color='red'>NOT SUPPORT</font> | 40.35 token/s |
|
||||
| [671B-DeepSeekV3] GPU memory (sum across GPUs) | theoretical 1400 GB † | <font color='red'>NOT SUPPORT</font> | 70 GB † |
|
||||
|
||||
† The **1400 GB** is the **theoretical** FP16 full-resident footprint (not runnable). **70 GB** is the **measured peak** with KT (Attention on GPU + layered MoE offload).
|
||||
|
||||
From the table above, it can be seen that for the 14B model, the KTransformers backend achieves approximately 75% higher throughput than the default HuggingFace solution, while using only about one-fifth of the GPU memory. For the 671B model, both HuggingFace and Unsloth fail to run on a single 4090 GPU, whereas KTransformers is able to perform LoRA fine-tuning at 40 tokens/s, keeping the GPU memory usage within 70 GB.
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## Overall View of the KT Fine-Tuning Framework
|
||||
|
||||
We detail how KTransformers takes over core operators in LLaMA-Factory’s fine-tuning framework to optimize Attention and MoE.
|
||||
|
||||
DeepSeek-V3/V2 MoE models comprise a small-parameter dense Attention part and a large-parameter sparse MoE part. For illustration, consider layer 2 of DeepSeek-V2-Lite-Chat (from which each layer includes both Attention and MoE). Attention compute and KV cache mainly reside on the GPU; the heavyweight MoE part is primarily executed on the CPU. We first cover **Attention replacement and inheritance**, then **MoE encapsulation and backend interfacing**, and finally **multi-GPU placement**.
|
||||
|
||||
### Attention (LoRA + KT coexist)
|
||||
|
||||
KTransformers provides operator injection (`BaseInjectedModule`), and PEFT provides LoRA layer insertion. For fine-tuning, we design `KTransformersLinearLora`, inheriting from both `KTransformersLinear` and `LoraLayer`:
|
||||
|
||||
- **Inheritance:** `KTransformersLinearLora` retains KT’s high-performance paths (`prefill_linear`/`generate_linear`) while accepting LoRA parameters (`lora_A/lora_B`).
|
||||
- **Replacement:** During preparation, we replace original `KTransformersLinear` layers (Q/K/V/O) with `KTransformersLinearLora`, preserving KT optimizations while enabling LoRA trainability.
|
||||
|
||||

|
||||
|
||||
After replacement, LoRA is inserted at Q/K/V/O linear transforms (left), and `KTransformersLinearLora` contains both KT fast paths and LoRA matrices (right).
|
||||
|
||||

|
||||
|
||||
### MoE (operator encapsulation + backward)
|
||||
|
||||
#### Encapsulation
|
||||
|
||||
Given large parameters and sparse compute, we encapsulate the expert computation as a **differentiable black-box operator**—transparent upstream, replaceable downstream.
|
||||
|
||||
- **Upstream (PyTorch graph):** we register a custom Autograd Function so the MoE layer appears as **a single node**. In the left figure (red box), only `KSFTExpertsCPU` is visible; on the right, the unencapsulated graph expands routing, dispatch, and FFN experts. Encapsulation makes the MoE layer behave like a standard `nn.Module` with gradients.
|
||||
- **Downstream (backend):** inside the Autograd Function, pybind11 calls C++ extensions for forward/backward. Multiple **pluggable backends** exist (AMX BF16/INT8; **llamafile**). The backend can be switched via YAML (e.g., `"backend": "AMXBF16"` vs. `"llamafile"`).
|
||||
|
||||

|
||||
|
||||
#### Backward (CPU)
|
||||
|
||||
MoE backward frequently needs the transposed weights $W^\top$. To avoid repeated runtime transposes, we **precompute/cache** $W^\top$ at load time (blue box). We also **cache necessary intermediate activations** (e.g., expert projections, red box) to reuse in backward and reduce recomputation. We provide backward implementations for **llamafile** and **AMX (INT8/BF16)**, with NUMA-aware optimizations.
|
||||
|
||||
<img src="../assets/image-20251016182942726.png" alt="image-20251016182942726" style="zoom:33%;" />
|
||||
|
||||
### Multi-GPU Loading/Training: Placement strategy instead of DataParallel
|
||||
|
||||
To lower **per-GPU memory peaks** on 2–4 GPUs, we use **model parallelism + explicit placement**, not DataParallel (which duplicates the whole model on each GPU).
|
||||
|
||||
Key changes:
|
||||
|
||||
1. **KTrainer:** takes over `.to(device)` to prevent “move whole model to a single GPU”. Using KT’s optimize-rule YAML, each layer declares `device: cuda:0/cuda:1/...` and is **constructed directly on the target GPU** (no extra copies).
|
||||
2. **Disable automatic DataParallel:** when `USE_KT=1`, we disable automatic DP wrappers from LLaMA-Factory/HF Trainer to avoid duplication and keep full control over sharding.
|
||||
3. **Gradient aggregation:** gradients are reduced to `cuda:0`. Intermediate activations stay local; only necessary tensors are transferred, cutting communication/activation overhead.
|
||||
|
||||
Thus, we keep KT placement strategies under multi-GPU fine-tuning. Users choose a `kt_optimize_rule` with `multi-gpu`. For DeepSeek-671B, `DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml` is a typical 2-GPU plan: KV/attention parts on each GPU; MoE experts sharded on CPU; both GPUs share the workload.
|
||||
|
||||
|
||||
|
||||
## KT-LoRA Fine-Tuning Evaluation
|
||||
|
||||
### Setup
|
||||
|
||||
LLaMA-Factory orchestration, KTransformers backend, LoRA (rank=8, α=32, dropout=0.1, BF16), `GAS=16`, `qlen=512`, with the same KT optimize rule as training. We evaluate (a) stylized dialogue transfer and (b) two **small-scale representative** benchmarks: Translational-Style (generative) and AfriMed-QA (medical vertical; **SAQ** and **MCQ**). AMX is enabled; GPUs: 2×48GB RTX 4090; CPU: Intel Xeon Platinum 8488C.
|
||||
|
||||
### Results
|
||||
|
||||
#### Stylized Dialogue (CatGirl tone)
|
||||
|
||||
Dataset: [NekoQA-10K](https://zhuanlan.zhihu.com/p/1934983798233231689). The fine-tuned model consistently exhibits the target style (red boxes) versus neutral/rational base (blue). This shows **KT-LoRA injects style features** into the generation distribution with low GPU cost.
|
||||
|
||||

|
||||
|
||||
#### Translational-Style benchmark (generative)
|
||||
|
||||
Dataset: [Translational-Style-ChatLLM](https://github.com/Benson114/Translational-Style-ChatLLM). Metrics: BLEU-1/2/3/4, ROUGE-1/2/L.
|
||||
|
||||
| Translational-Style dataset | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.41** | **22.44** | **15.42** | **11.18** | **42.03** | **18.38** | **33.10** |
|
||||
| V3 base (no LoRA) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
|
||||
| **KT-LoRA fine-tuned V3** | **37.02** | **23.70** | **16.21** | **11.49** | **43.43** | **18.96** | **34.54** |
|
||||
|
||||
As shown by the test results in the tables above, under a unified workflow and placement strategy, **both model scales exhibit consistent gains after fine-tuning**, supporting the usability and effectiveness of the “KT backend + LoRA fine-tuning” combination for generative style control. At the same time, this indicates that KT’s heterogeneous placement and operator optimizations can stably support small-sample adaptation in the style domain.
|
||||
|
||||
#### Medical Vertical Benchmark (AfriMed-SAQ/MCQ)
|
||||
|
||||
The dataset adopts [AfriMed-QA](https://aclanthology.org/2025.acl-long.96/) (ACL 2025), a domain-specific dataset for the medical field in Africa with strong scenario customization characteristics, comprising two formats—multiple-choice questions (MCQ) and short-answer questions (SAQ)—which in this case serve as the evaluation for vertical-domain fine-tuning. In terms of evaluation criteria, BLEU/ROUGE are used for SAQ, and Accuracy is used for MCQ.
|
||||
|
||||
| AfriMed-QA (SAQ) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------ | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite (no LoRA) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **35.90** | **27.63** | **22.99** | **19.15** | **35.25** | **17.50** | **28.44** |
|
||||
| V3 base (no LoRA) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
|
||||
| **KT-LoRA fine-tuned V3** | **42.42** | **34.12** | **28.95** | **24.54** | **41.97** | **22.37** | **33.28** |
|
||||
|
||||
| AfriMed-QA (MCQ) | Accuracy |
|
||||
| ------------------------------ | ---------- |
|
||||
| V2-Lite (no LoRA) | 0.0645 |
|
||||
| **KT-LoRA fine-tuned V2-Lite** | **0.4812** |
|
||||
| V3 base (no LoRA) | 0.5833 |
|
||||
| **KT-LoRA fine-tuned V3** | **0.7930** |
|
||||
|
||||
As shown in the tables above, (1) DeepSeek-V3 (671B) after KT-LoRA fine-tuning achieves clearly higher performance than the fine-tuned DeepSeek-V2-Lite (14B) on both MCQ and SAQ, and it also surpasses the V3 base model. Within our small-scale setting, this preliminarily indicates that KT-LoRA fine-tuning of ultra-large-parameter models has practical significance in vertical domains.
|
||||
|
||||
(2) Across both SAQ/MCQ sub-tasks, KT-LoRA delivers consistent gains, indicating that—with KT’s heterogeneous placement and backend operator support—LoRA fine-tuning can effectively inject the key knowledge points of vertical domains such as medicine into the model.
|
||||
|
||||
#### Limitations
|
||||
|
||||
At present, most of our testing is conducted on **single datasets** and at **small scale** (≤ 20k examples), with the goal of providing **existence evidence of system effectiveness for KT-LoRA fine-tuning**, rather than drawing generalized conclusions about algorithmic generalization or scaling laws. Our report primarily presents representative figures; to support stronger algorithmic claims, larger sample sizes, multi-lingual/multi-domain datasets, and multi-seed repeated experiments would be required—these are beyond the scope of this work.
|
||||
|
||||
**We also warmly welcome everyone to join the open-source LLaMA-Factory KT fine-tuning project. If you have additional test results, we especially welcome you to record them in the shared spreadsheet below, and to include the corresponding `kt_optimize_rule` files, dataset examples, training/evaluation YAMLs, and detailed GPU-memory and CPU configurations for community reference and reproducibility~!**
|
||||
|
||||
|
||||
|
||||
### Speed Tests
|
||||
|
||||
#### End-to-End Performance
|
||||
|
||||
**Definitions**
|
||||
|
||||
`step_time`:time per optimization step (tensor movement + Attention + MoE + others).
|
||||
|
||||
`tokens_per_step = GAS × qlen`;`token/s = tokens_per_step / step_time`。 We use `GAS=16`, `qlen=512` → `tokens_per_step=8192`.
|
||||
|
||||
**Measured**
|
||||
|
||||
| Model | step_time (s) | tokens/step | token/s |
|
||||
| -------------------- | ------------- | ----------- | --------- |
|
||||
| DeepSeek-V3-671B | 203 | 8192 | **40.35** |
|
||||
| DeepSeek-V2-Lite-14B | 36 | 8192 | **227.6** |
|
||||
|
||||
#### MoE Compute (DeepSeek-V3-671B)
|
||||
|
||||
**Theory**
|
||||
|
||||
- MoE per-layer, per-token FLOPs (forward+backward) approx.:
|
||||
$$
|
||||
\text{FLOPs}_{\text{per-layer, per-token}} \approx c \cdot k \cdot H \cdot I
|
||||
$$
|
||||
|
||||
with $k = 8$(Top-k),$H = 7168$(hidden size),$I = 2048$(intermediate size),$c\approx16$(≈6 forward + ≈10 backward matmuls)。
|
||||
|
||||
- Per-step across all MoE layers:
|
||||
$$
|
||||
\text{FLOPs}_{\text{per-step}} \approx c \cdot qlen \cdot k \cdot H \cdot I \cdot L_{\text{MoE}}
|
||||
$$
|
||||
|
||||
Plugging $c=16, qlen=512, k=8, H=7168, I=2048, L_{MoE}=58$,$\text{FLOPs}_{\text{per-step}} \approx 55.8\ \text{TFLOPs}$.
|
||||
|
||||
**Measured (MoE TFLOPS on CPU)**
|
||||
|
||||
If the **MoE-only** time per step is `t_moe` (seconds), $\text{TFLOPS} = \text{FLOPs}_{\text{per-step}} / \text{step\_per\_second}.$
|
||||
|
||||
Use MoE-phase time, not full `step_time`, to get MoE throughput.
|
||||
|
||||
| TFLOPS | Forward | Backward |
|
||||
| ------- | ------- | -------- |
|
||||
| Average | 17.55 | 18.41 |
|
||||
|
||||
### Memory Footprint
|
||||
|
||||
- DeepSeek-V3 (671B; 58 MoE layers out of 61): ~**70 GB** total GPU, ~**1.2–1.3 TB** host memory.
|
||||
- DeepSeek-V2-Lite (14B; 26 MoE layers out of 27): ~**5 GB** GPU, ~**30 GB** host memory.
|
||||
|
||||
|
||||
|
||||
## Conclusion
|
||||
|
||||
Integrating **KTransformers LoRA** with **LLaMA-Factory** provides a practical path to efficiently train and deploy MoE LLMs. KT contributes placement strategies and operator optimizations (DeepSeek/Qwen/Kimi support with AMX-accelerated kernels), and LoRA enables customization with very low GPU memory; LLaMA-Factory supplies a coherent user-level interface.
|
||||
|
||||
This means even tens-to-hundreds-of-billion-parameter MoE models can be fine-tuned and served with low latency on ordinary hardware. The approach balances **memory savings**, **speed**, and **usability**, turning ultra-large models into tools that developers can actually wield.
|
||||
302
doc/zh/KTransformers Fine-Tuning -- User Guide_zh.md
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
- [KTransformers 微调 × LLaMA-Factory 集成 – 用户指南](#ktransformers-微调-x-llama-factory-集成-–-用户指南)
|
||||
- [Introduction](#introduction)
|
||||
|
||||
- [Quick to Start](#quick-to-start)
|
||||
- [快速上手](#快速上手)
|
||||
- [环境安装](#环境安装)
|
||||
- [核心功能1:使用KTransformers作为backend,微调超大规模MoE模型](#核心功能1使用ktransformers作为backend微调超大规模moe模型)
|
||||
- [核心功能2:与微调后模型(即原模型+LoRA Adapter)聊天,用于交互](#核心功能2与微调后模型即原模型lora-adapter聊天用于交互)
|
||||
- [核心功能3:生成微调后模型(即原模型+LoRA Adapter)的API,用于批量生成并评测指标](#核心功能3生成微调后模型即原模型lora-adapter的api用于批量生成并评测指标)
|
||||
|
||||
- [KT微调速度性能测试:用户侧](#kt微调速度性能测试用户侧)
|
||||
- [端到端性能](#端到端性能)
|
||||
- [显存/内存性能](#显存内存性能)
|
||||
|
||||
- [结论](#结论)
|
||||
|
||||
# KTransformers 微调 × LLaMA-Factory 集成 – 用户指南
|
||||
|
||||
**MadSys实验室, KVCache-AI团队, 趋境科技, LLaMA-Factory团队**
|
||||
|
||||
## Introduction
|
||||
|
||||
从 **DeepSeek-V3/R1** 到 **Qwen3-MoE、Kimi-K2**,每一次超大模型的开源都带来性能与规模上的巨大跃升。然而,多数研究者与开发者受限于昂贵的显卡与动辄数千亿参数的模型,**难以在资源受限条件下微调超大模型**。面对这种差距,我们提出了一种更具可行性的方案:通过 **KTransformers 与 LLaMA-Factory 的结合**,仅需2~4张RTX 4090与较高内存CPU,便可微调DeepSeek-671B等超大规模的MoE模型。
|
||||
|
||||
该架构的核心目标是为资源受限下的研究者提供 **在本地探索超大规模模型微调的可能性**。同时,也在较小规模(如 14B/30B)提供快速定制特定场景的路径。我们以**风格化对话、西式腔调翻译、医学问答**作为代表任务,验证架构的可行性,并展示在**数小时内达成个性化适配**的可操作性。
|
||||
|
||||
|
||||
|
||||
如下图所示,LLaMA-Factory 是整个微调流程的统一调度与配置框架,负责数据处理、训练调度、LoRA 插入与推理接口管理; KTransformers 则作为其可插拔的高性能后端,在相同的训练配置下接管 Attention / MoE 等核心算子,实现异构设备(GPU+CPU)的高效协同。
|
||||
|
||||

|
||||
|
||||
我们在 LLaMA-Factory 框架下,对比评测了 **HuggingFace**、**Unsloth**、**KTransformers** 三种后端的 LoRA 微调方案。结果显示,KTransformers为超大规模的MoE模型(671B等)提供了**4090 级别**的唯一可行方案,并在较小规模的MoE模型(DeepSeek-14B)上面也展现了更高的吞吐和更低的显存占用。
|
||||
|
||||
| Under LoRA (BF16)+[NekoQA-10K-风格化对话数据集](https://github.com/mindsRiverPonder/LLM-practice) | HuggingFace Backend | Unsloth Backend | KTransformers Backend |
|
||||
| ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------ | --------------------- |
|
||||
| [14B-DeepSeekV2-Lite] LoRA Fine-tuning throughput | 303.58 token/s | 455.37 token/s | 530.38 token/s |
|
||||
| [14B-DeepSeekV2-Lite] GPU Memory | 32.12 GB | 9.64 GB | 6.08 GB |
|
||||
| [671B-DeepSeekV3] LoRA Fine-tuning throughput | <font color='red'>Too Huge to run</font> | <font color='red'>NOT SUPPORT</font> | 40.35 token/s |
|
||||
| [671B-DeepSeekV3] GPU Memory(多卡总和) | 理论值1400 GB † | <font color='red'>NOT SUPPORT</font> | 70 GB † |
|
||||
|
||||
† **1400 GB** 为**理论显存**(FP16 全参数常驻,非可运行配置);**70 GB** 为 KT 策略(Attention 驻 GPU + MoE分层 offload)下的**实测峰值**。
|
||||
|
||||

|
||||
|
||||
### 微调效果示例
|
||||
|
||||
#### 风格化对话测试(CatGirl风格语气)
|
||||
|
||||
数据集:[NekoQA-10K: 面向猫娘语言建模的对话数据集](https://zhuanlan.zhihu.com/p/1934983798233231689),目标是提升风格一致性与可辨识度。
|
||||
|
||||
下图对比了原始模型和微调模型的回答,可以看到微调后模型在语气和称谓上更加稳定地保持了猫娘风格(红框部分),验证了**风格迁移微调**的有效性。
|
||||
|
||||

|
||||
|
||||
#### Benchmark测试
|
||||
|
||||
数据集选取:
|
||||
|
||||
(1)采用了[西式翻译腔数据集](https://github.com/Benson114/Translational-Style-ChatLLM),该数据集要求模型按西式表达习惯进行夸张的翻译,有明确的定制化风格需求。
|
||||
|
||||
(2)采用了[AfriMed-QA](https://aclanthology.org/2025.acl-long.96/)数据集(ACL-2025),作为非洲地区医疗领域的专用数据集,具有很强的场景定制特征,包含选择题和简答题两种形式,非常适合作为垂直领域微调的评估。针对单选和简答形式,我们分别进行测试,结果如下。
|
||||
|
||||
下表显示了微调前后模型在这些数据集上的指标变化。可以看到经过 LoRA 微调后,各项指标**大幅提升**,验证了微调的有效性:
|
||||
|
||||
| 西式翻译腔数据集 | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **35.41** | **22.44** | **15.42** | **11.18** | **42.03** | **18.38** | **33.10** |
|
||||
| V3原模型(不LoRA微调) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **37.02** | **23.70** | **16.21** | **11.49** | **43.43** | **18.96** | **34.54** |
|
||||
|
||||
| AfriMed-QA数据集(简答任务) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **35.90** | **27.63** | **22.99** | **19.15** | **35.25** | **17.50** | **28.44** |
|
||||
| V3原模型(不LoRA微调) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **42.42** | **34.12** | **28.95** | **24.54** | **41.97** | **22.37** | **33.28** |
|
||||
|
||||
| AfriMed-QA数据集(单选任务) | Accuracy |
|
||||
| ------------------------------- | ---------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 0.0645 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **0.4812** |
|
||||
| V3原模型(不LoRA微调) | 0.5833 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **0.7930** |
|
||||
|
||||
从以上测试可以看出,即使是参数量巨大的 MoE 模型,通过 KTransformers 后端的高效微调,**也能在特定任务上快速达到理想效果**。
|
||||
|
||||
|
||||
|
||||
## Quick to Start
|
||||
|
||||
### 快速上手
|
||||
|
||||
本节将指导您如何安装环境并使用 **LLaMA-Factory + KTransformers** 完成微调和推理。我们将涵盖以下内容:
|
||||
|
||||
- 环境依赖的安装配置
|
||||
- 使用 KTransformers 作为后端微调超大规模 MoE 模型
|
||||
- 加载微调后的模型(原模型 + LoRA 适配器)进行对话/推理
|
||||
- 批量推理微调模型并评测指标
|
||||
|
||||
### 环境安装
|
||||
|
||||
根据下面示例,同时安装KTransformers和LLaMA-Factory环境,这次为了简化KTransformers的安装流程,我们特意封装了wheel包避免本地编译,具体安装步骤如下:(注意对应好本地的python版本、torch版本、cuda版本和不同文件名的KTransformers包)
|
||||
|
||||
```shell
|
||||
# 1. 安装conda环境
|
||||
conda create -n Kllama python=3.10 # choose from : [3.10, 3.11, 3.12, 3.13]
|
||||
conda install -y -c conda-forge libstdcxx-ng gcc_impl_linux-64
|
||||
conda install -y -c nvidia/label/cuda-11.8.0 cuda-runtime
|
||||
|
||||
# 2. 安装llamafactory环境
|
||||
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
|
||||
cd LLaMA-Factory
|
||||
pip install -e ".[torch,metrics]" --no-build-isolation
|
||||
|
||||
# 3. 安装对应torch和python版本的KTransformers(CUDA版本可以跟whl命名的不一致)
|
||||
pip install ktransformers-0.4.1+cu128torch28fancy-cp310-cp310-linux_x86_64.whl
|
||||
|
||||
# 4. 安装flash-attention,参照python版本和torch版本,从https://github.com/Dao-AILab/flash-attention/releases下载
|
||||
https://github.com/Dao-AILab/flash-attention/releases/download/v2.8.3/flash_attn-2.8.3+cu12torch2.8cxx11abiTRUE-cp310-cp310-linux_x86_64.whl
|
||||
# abi=True/False可以用下面代码查看
|
||||
# import torch
|
||||
# print(torch._C._GLIBCXX_USE_CXX11_ABI)
|
||||
|
||||
# 5. (可选)如果你想使用flash_infer的话(不然默认triton)
|
||||
git clone https://github.com/kvcache-ai/custom_flashinfer.git
|
||||
pip install custom_flashinfer/
|
||||
```
|
||||
|
||||
|
||||
|
||||
**使用要点**:在 LLaMA-Factory 的配置 YAML 文件中启用 KTransformers 后端,只需设置 `use_kt: true`,并指定相应的 `kt_optimize_rule` YAML 文件,即可切换到底层由 KTransformers 接管计算。下面我们将通过具体功能来说明如何设置这些配置。
|
||||
|
||||
### 核心功能1:使用KTransformers作为backend,微调超大规模MoE模型
|
||||
|
||||
运行命令:`USE_KT=1 llamafactory-cli train examples/train_lora/deepseek3_lora_sft_kt.yaml`。
|
||||
|
||||
需要注意的是,必须提供BF16格式模型文件,DeepSeek-V3-671B默认下载是FP8格式,需要通过 [DeepSeek-V3/inference/fp8_cast_bf16.py](https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/fp8_cast_bf16.py) 转换。
|
||||
|
||||
```yaml
|
||||
### model
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
trust_remote_code: true
|
||||
|
||||
### method
|
||||
stage: sft
|
||||
do_train: true
|
||||
finetuning_type: lora
|
||||
lora_rank: 8
|
||||
lora_target: all
|
||||
|
||||
### dataset
|
||||
dataset: identity
|
||||
template: deepseek
|
||||
cutoff_len: 2048
|
||||
max_samples: 100000
|
||||
overwrite_cache: true
|
||||
preprocessing_num_workers: 16
|
||||
dataloader_num_workers: 4
|
||||
|
||||
### output
|
||||
output_dir: saves/Kllama_deepseekV3
|
||||
logging_steps: 10
|
||||
save_steps: 500
|
||||
plot_loss: true
|
||||
overwrite_output_dir: true
|
||||
save_only_model: false
|
||||
report_to: none # choices: [none, wandb, tensorboard, swanlab, mlflow]
|
||||
|
||||
### train
|
||||
per_device_train_batch_size: 1
|
||||
gradient_accumulation_steps: 8
|
||||
learning_rate: 1.0e-4
|
||||
num_train_epochs: 3.0
|
||||
lr_scheduler_type: cosine
|
||||
warmup_ratio: 0.1
|
||||
bf16: true
|
||||
ddp_timeout: 180000000
|
||||
resume_from_checkpoint: null
|
||||
|
||||
### ktransformers
|
||||
use_kt: true # use KTransformers as LoRA sft backend
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
其中,`kt_optimize_rule`提供了大量默认的YAML文件来控制**KTransformers的放置策略**,下面针对YAML文件名和功能对照特别说明,也可以参考[ktransformers/optimize_rules](https://github.com/kvcache-ai/ktransformers/tree/main/ktransformers/optimize/optimize_rules):(\*指通配符)
|
||||
|
||||
| 文件名字段 | 功能特征 |
|
||||
| --------------------------------------------- | -------------------------------------------------- |
|
||||
| DeepSeek-V2-Lite-Chat-\*或DeepSeek-V3-Chat-\* | 对应的不同模型 |
|
||||
| \*-sft-\* | 微调所用的放置策略,其他为推理所用 |
|
||||
| \*-amx-\* | 使用AMX指令集进行CPU运算,其他为llamafile |
|
||||
| \*-multi-gpu-X\* | 使用X张GPU进行模型并行(显存共担),X为空默认是2张 |
|
||||
|
||||
例如:`examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml`为DeepSeek-V3-Chat模型用AMX指令集进行微调,并调用两卡模型并行。
|
||||
|
||||
对于微调任务,我们推荐使用**AMX指令集加速**,可以使用`lscpu | grep amx`查看CPU是否支持AMX指令集,AMX精度支持BF16/Int8,修改方式如下:
|
||||
|
||||
```yaml
|
||||
- match:
|
||||
name: "^model\\.layers\\..*\\.mlp\\.experts$"
|
||||
replace:
|
||||
class: ktransformers.operators.experts.KTransformersExperts # custom MoE Kernel with expert parallelism
|
||||
kwargs:
|
||||
prefill_device: "cpu"
|
||||
prefill_op: "KExpertsTorch"
|
||||
generate_device: "cpu"
|
||||
generate_op: "KSFTExpertsCPU"
|
||||
out_device: "cuda"
|
||||
backend: "AMXInt8" # or "AMXBF16" or "llamafile" (default)
|
||||
```
|
||||
|
||||
输出会保存在`output_dir`里面,默认为safetensor格式,并且保留adapter.json等配套内容以便后续加载。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 核心功能2:与微调后模型(即原模型+LoRA Adapter)聊天,用于交互
|
||||
|
||||
运行命令:`llamafactory-cli chat examples/inference/deepseek3_lora_sft_kt.yaml`。
|
||||
|
||||
调用KT微调的adapter (safetensor格式) 推理对话。
|
||||
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
use_kt: true # 调用KTransformers backend
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx.yaml # 请选择和LoRA微调的时候保持一致的YAML文件
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
同时,我们也支持GGUF格式的adapter进行推理(如果您已经使用了上述LLaMA-Factory+KTransformers的微调方案,就不用管啦~)。
|
||||
|
||||
safetensors 场景填**文件所在目录**,GGUF 场景填**文件路径**,也就是说您需要把`adapter_name_or_path`选为具体的GGUF格式文件。
|
||||
|
||||
加载过程中适配了KT每层的命名,和torch.save保存下来的常规命名的不同,正常映射日志`Loaded adapter weight: XXX -> XXX`,展示如下。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 核心功能3:生成微调后模型(即原模型+LoRA Adapter)的API,用于批量生成并评测指标
|
||||
|
||||
运行命令:`API_PORT=8000 llamafactory-cli api examples/inference/deepseek3_lora_sft_kt.yaml`。
|
||||
|
||||
调用KT微调的adapter给出API,其他API使用逻辑和llamafactory原生方式一致。
|
||||
|
||||
```yaml
|
||||
model_name_or_path: opensourcerelease/DeepSeek-V3-bf16
|
||||
adapter_name_or_path: saves/Kllama_deepseekV3
|
||||
template: deepseek
|
||||
infer_backend: ktransformers # choices: [huggingface, vllm, sglang, ktransformers]
|
||||
trust_remote_code: true
|
||||
|
||||
use_kt: true # use KTransformers as LoRA sft backend to inference
|
||||
kt_optimize_rule: examples/kt_optimize_rules/DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml
|
||||
cpu_infer: 32
|
||||
chunk_size: 8192
|
||||
```
|
||||
|
||||
|
||||
|
||||
## KT微调速度性能测试:用户侧
|
||||
|
||||
### 端到端性能
|
||||
|
||||
**测试定义:**
|
||||
|
||||
`step_time`:一次优化步(包含 `gradient_accumulation_steps (GAS)` 次累积)的总时间,涵盖 **PyTorch 张量搬运 + Attention + MoE + 其他计算等**。
|
||||
|
||||
`tokens_per_step = GAS × qlen`;`token/s = tokens_per_step / step_time`。
|
||||
|
||||
**测试设置:**`GAS=16`,`qlen=512`(即每步 8192 tokens);LoRA(`r=8, alpha=32, dropout=0.1`);使用AMX指令集优化;GPU选取RTX 4090,CPU选取Intel Xeon Platinum 8488C。
|
||||
|
||||
**实测结果:**
|
||||
|
||||
**DeepSeek-V3-671B:**step_time = 203 s` → `token/s ≈ 8192 / 203 **≈ 40.35 token/s**
|
||||
|
||||
**DeepSeek-V2-Lite-14B:**step_time = 36 s` → `token/s ≈ 8192 / 36 **≈ 227.6 token/s**
|
||||
|
||||
### 显存/内存性能
|
||||
|
||||
DeepSeek-V3(671B,61层,其中58层有MoE)占用显存(多卡总量)大约**70GB**、内存占用约1.2-1.3TB。
|
||||
|
||||
DeepSeek-V2-lite(14B,27层,其中26层有MoE)占用显存大约**5.5GB**、内存占用约150GB。
|
||||
|
||||
|
||||
|
||||
## 结论
|
||||
|
||||
通过开发 KTransformers LoRA微调并将其集成到 LLaMA‑Factory,我们为希望高效训练与部署 MoE 大模型的用户提供了可行指南。KT 带来最尖端的优化(支持 DeepSeek、Qwen、Kimi 等,配合 AMX 加速 kernel),同时通过 LoRA 微调在极低 GPU 显存下实现定制化。LLaMA‑Factory 则提供友好的统一界面,更广的用户支持。
|
||||
|
||||
该集成(类似 Unsloth 补丁所带来的提速)意味着即便是数百亿乃至万亿总参数量的 MoE 模型,也可在普通硬件上完成微调并低延迟部署。**显存节省、速度提升、易用性** 三者兼得。我们鼓励用户在下一次 MoE 项目中尝试 LLaMA‑Factory 的 KT 集成,并参考本文档进行操作。也欢迎提出任何问题和建议!
|
||||
|
|
@ -0,0 +1,227 @@
|
|||
- [KTransformers 微调 × LLaMA-Factory 集成 – 开发技术篇](#ktransformers-微调-x-llama-factory-集成-–-开发技术篇)
|
||||
- [Introduction](#introduction)
|
||||
|
||||
- [KT微调框架整体性描述](#kt微调框架整体性描述)
|
||||
- [Attention 部分(LoRA + KT 特性并存)](#attention-部分lora--kt-特性并存)
|
||||
- [继承关系](#继承关系)
|
||||
- [替换策略](#替换策略)
|
||||
- [MoE 部分(算子封装+backward实现)](#moe-部分算子封装backward实现)
|
||||
- [MoE算子封装](#moe算子封装)
|
||||
- [MoE 反向优化 (CPU 实现)](#moe-反向优化-cpu-实现)
|
||||
- [多卡加载与训练:用“放置策略”而不是 DataParallel](#多卡加载与训练用放置策略而不是-dataparallel)
|
||||
|
||||
- [KT-LoRA微调测试](#kt-lora微调测试)
|
||||
- [实验设置](#实验设置)
|
||||
- [效果测试](#效果测试)
|
||||
- [风格化对话测试(CatGirl语气)](#风格化对话测试catgirl语气)
|
||||
- [生成式翻译风格基准测试](#生成式翻译风格基准测试)
|
||||
- [医疗垂直领域基准(AfriMed-SAQ/MCQ)](#医疗垂直领域基准afrimed-saqmcq)
|
||||
- [局限性说明](#局限性说明)
|
||||
|
||||
- [速度测试](#速度测试)
|
||||
- [端到端性能](#端到端性能)
|
||||
- [MoE部分的计算性能(DeepSeek-V3-671B)](#moe部分的计算性能deepseek-v3-671b)
|
||||
|
||||
- [显存/内存性能](#显存内存性能)
|
||||
|
||||
- [结论](#结论)
|
||||
|
||||
# KTransformers 微调 × LLaMA-Factory 集成 – 开发技术篇
|
||||
|
||||
**MadSys实验室, KVCache-AI团队, 趋境科技, LLaMA-Factory团队**
|
||||
|
||||
## Introduction
|
||||
|
||||
当今的开源大模型(从 DeepSeek-V3/R1 到 Qwen-MoE 系列以及 Kimi-K2 等)在性能和规模上突飞猛进。然而,受限于**计算资源和显存**,普通研究者难以对这些上千亿乃至更大规模的模型进行微调。为此,我们设计了 **KTransformers** 与 **LLaMA-Factory** 集成的方案,使得仅需 **2~4 张 RTX 4090 GPU** 加上足够的 CPU 内存,就能微调 DeepSeek-671B 这样的超大规模 Mixture-of-Experts (MoE) 模型。
|
||||
|
||||
这一架构旨在桥接资源鸿沟,让更多人能够**在本地探索超大模型微调**的可能;同时在相对小一些的模型(如 14B/30B 参数量级)上,也能提供**更高效的场景化定制**途径。我们通过风格化对话、西式翻译语气、医学问答等任务验证了该方案,仅用数小时即可实现模型风格和专业领域的**快速适配**。
|
||||
|
||||
从系统架构上看,如下图所示,**LLaMA-Factory** 扮演微调流程的调度中枢,负责统一配置数据和训练流程、插入 LoRA 模块以及管理推理接口;**KTransformers** 则作为可插拔的高性能算子后端,在相同的训练代码下接管底层 **Attention** 和 **MoE** 运算,实现 **GPU+CPU 异构协同**,加速训练并降低显存占用。
|
||||
|
||||

|
||||
|
||||
为评估该集成的性能优势,我们使用 LLaMA-Factory 分别调用了 HuggingFace 默认后端、Unsloth 后端以及 KTransformers 后端进行 LoRA 微调的对比测试(在相同设置和数据集下)。结果表明,**KTransformers** 是目前唯一能在 2~4 张 24GB 4090卡上微调 **671B 规模 MoE 模型** 的方案;同时在 14B 规模的 MoE 模型上,相比另两种方案也具有**更高的吞吐速率**和**更低的 GPU 显存占用**。
|
||||
|
||||
| Under LoRA (BF16)+[NekoQA-10K-风格化对话数据集](https://github.com/mindsRiverPonder/LLM-practice) | HuggingFace Backend | Unsloth Backend | KTransformers Backend |
|
||||
| ------------------------------------------------------------ | ---------------------------------------- | ------------------------------------ | --------------------- |
|
||||
| [14B-DeepSeekV2-Lite] LoRA Fine-tuning throughput | 303.58 token/s | 455.37 token/s | 530.38 token/s |
|
||||
| [14B-DeepSeekV2-Lite] GPU Memory | 32.12 GB | 9.64 GB | 6.08 GB |
|
||||
| [671B-DeepSeekV3] LoRA Fine-tuning throughput | <font color='red'>Too Huge to run</font> | <font color='red'>NOT SUPPORT</font> | 40.35 token/s |
|
||||
| [671B-DeepSeekV3] GPU Memory(多卡总和) | 理论值1400 GB † | <font color='red'>NOT SUPPORT</font> | 70 GB † |
|
||||
|
||||
† **1400 GB** 为**理论显存**(FP16 全参数常驻,非可运行配置);**70 GB** 为 KT 策略(Attention 驻 GPU + MoE分层 offload)下的**实测峰值**。
|
||||
|
||||
上表中可以看出,对于 14B 模型,KTransformers 后端的吞吐量相比 HuggingFace 默认方案提升了约 75%,而显存占用仅为其约 1/5。对于 671B 模型,HuggingFace 和 Unsloth 在单台4090环境下无法运行,而 KTransformers 能以 **40 tokens/s** 的速度LoRA微调,并将 GPU 显存需求控制在 70 GB。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## KT微调框架整体性描述
|
||||
|
||||
下面详细展示的是在 LLaMA-Factory 的微调框架中,KTransformers 后端如何接管底层算子并实现 Attention / MoE 的优化结构。
|
||||
|
||||
DeepSeek-V3/V2等MoE模型主要包括小参数、密集矩阵的Attention部分和大参数、稀疏矩阵的MoE部分。为了直观说明,我们以 DeepSeek-V2-Lite-Chat 的第 2 层为例(从该层起,每层包含 Attention 与 MoE 两个子模块),其中Attention由GPU承担主要计算与缓存(KV),剩下的大参数量MoE主要由CPU承担 。下文将先介绍 **Attention 部分的替换与继承关系**,再介绍 **MoE 部分的封装与后端对接**,最后说明**多卡放置等特性支持**。
|
||||
|
||||
### Attention 部分(LoRA + KT 特性并存)
|
||||
|
||||
KTransformers 提供了算子模块的注入机制(`BaseInjectedModule`),而 PEFT 库提供了 LoRA 微调的层插入机制。为了在**微调阶段**同时兼容两者,我们设计了 `KTransformersLinearLora` 类,使其同时继承自 KTransformers 的线性层 (`KTransformersLinear`) 和 LoRA 的层基类 (`LoraLayer`)。如下图所示:
|
||||
|
||||
- **继承关系**:如下图所示,`KTransformersLinearLora` 同时继承 `KTransformersLinear` 与 `LoraLayer`,既保留 **KT 的高性能算子**(如 `prefill_linear` / `generate_linear`),又能**加载 LoRA参数**(如 `lora_A`、`lora_B` 等矩阵);
|
||||
|
||||
- **替换策略**:在微调准备阶段,用 `KTransformersLinearLora` **逐一替换** 原 `KTransformersLinear`层(如下图右侧所示,主要包含Q/K/V/O 等线性层),从而在不破坏 KT 优化的前提下,将 LoRA 注入到了模型中,使其参数可训练。
|
||||
|
||||

|
||||
|
||||
替换完成后,如下图(左)所示,在计算图中相当于在原模型的 Q/K/V/O 四个矩阵乘法位置都插入了 LoRA。下图(右)展示了 `KTransformersLinearLora` 的内部,它同时包含了 KT 模块的高性能计算接口(prefill 和 generate 阶段的方法)以及 LoRA 的 A、B 矩阵等参数。
|
||||
|
||||

|
||||
|
||||
### MoE 部分(算子封装+backward实现)
|
||||
|
||||
#### MoE算子封装
|
||||
|
||||
考虑到 MoE 参数量大且计算稀疏,我们采用“封装成黑盒算子”的策略处理:将 MoE 专家计算封装为一个**对上游而言透明(单节点)、对下游可替换(多实现)**的可微算子。
|
||||
|
||||
- **上游(PyTorch 计算图)**:我们注册自定义 Autograd Function,整个 MoE 专家层在计算图中呈现为**一个节点**。如下左图红框所示,封装后计算图中只有 `KSFTExpertsCPU` 这样一个算子节点;而右图红框为未封装时的细粒度计算图——路由、专家选择以及 FFN 计算都完整展开在计算图中。封装后,对微调过程来说,MoE层就等同于一个普通 `nn.Module`,前向计算可求梯度,反向梯度也由我们来自定义算子返回。
|
||||
- **下游(后端实现)**:在这个 Autograd Function 内部,我们通过 pybind11 调用了 C++ 扩展实现具体的前向和反向计算。这里我们提供了多个**可插拔后端实现**,如 AMX 指令集版本(支持 BF16/INT8 算子优化)和 llamafile 版本。只要遵循同样的接口,即可灵活切换后端。例如在 YAML 优化规则里指定使用 `"backend": "AMXBF16"`,就会调用 AMX 后端;改成 `"llamafile"` 则使用默认后端。
|
||||
|
||||

|
||||
|
||||
#### MoE 反向优化 (CPU 实现)
|
||||
|
||||
在实现 MoE 自定义算子的反向传播时,我们特别优化了大矩阵的梯度计算开销。MoE反向计算需要频繁访问权重转置`Wᵀ`,为避免运行时反复转置带来的开销,我们在加载参数时**预备一份权重转置`Wᵀ` 便于复用**(如下图蓝框)。同时,**缓存必要的中间激活**(例如专家层中间投影结果,见下图红框),以便在反向阶段复用,减少重复计算。基于这些缓存,当前已提供 llamafile 与 AMX(INT8/BF16) 的MoE反向计算实现,并针对 NUMA 架构优化内存访问。
|
||||
|
||||
<img src="../assets/image-20250911184455749.png" alt="image-20250911184455749" style="zoom: 33%;" />
|
||||
|
||||
### 多卡加载与训练:用“放置策略”而不是 DataParallel
|
||||
|
||||
为了在使用 2~4 张 GPU 时进一步降低**单卡显存压力**,KTransformers 结合模型并行技术实现了**多卡协同微调**。与常规的 DataParallel 不同,我们没有简单地将整层模型复制到每张卡(那样显存需求会翻倍),而是采用**模型并行 + 显式算子放置**的策略,让不同 GPU 各自承载模型的一部分层。
|
||||
|
||||
具体而言,我们对 Transformers Trainer 做了以下改动:
|
||||
|
||||
1. **自定义训练器 (KTrainer)**:接管模型加载到设备的逻辑,采用显示层放置。默认情况下 `transformers` 会在初始化时将模型 `.to(device)` 全部搬移到单块 GPU,我们通过自定义 KTrainer 阻止这一行为,利用 KTransformers 的优化规则 YAML,我们可以在每一层声明 `device: cuda:0/cuda:1/...` 来指定该层所在的设备。这样初始化模型时,各层就直接构建在目标 GPU 上,不需要额外拷贝。。
|
||||
|
||||
2. **禁用自动 DataParallel**:当启动全局变量`USE_KT=1`时,我们暂时禁用了 LLaMA-Factory 和 HuggingFace Train 原本自动启动的多卡 DataParallel 封装。避免了框架层面对模型的重复拷贝,使我们能够完全掌控模型的分片方案。
|
||||
|
||||
3. **梯度回传与汇总**:由于模型各部分分散在不同 GPU 上,我们采取梯度汇总到 `cuda:0` 的方式。具体做法是:在反向传播时,仅将所需的梯度张量在设备间传输,而不传输整个模型的中间激活;各 GPU 计算各自部分的梯度,最终在0号卡汇总计算 loss。这种方式减少了不必要的通讯开销和激活冗余。
|
||||
|
||||
通过上述手段,我们实现了**多 GPU 下依然遵循 KTransformers 放置策略**的训练方案。用户只需选择合适的 `kt_optimize_rule` 配置文件(例如带有 `multi-gpu` 的 YAML),即可启用默认的模型分片方案。在 DeepSeek-671B 微调中,我们提供的 `DeepSeek-V3-Chat-sft-amx-multi-gpu.yaml` 就是一个两卡模型并行的典型策略:Attention 模块的 KV缓存和部分计算放在每张卡上,MoE 专家层在 CPU 上分片处理,两张卡共同承担全模型的计算。
|
||||
|
||||
|
||||
|
||||
## KT-LoRA微调测试
|
||||
|
||||
### 实验设置
|
||||
|
||||
实验均采用 LLaMA-Factory 调度、KTransformers 后端、LoRA 轻量微调范式(超参数:rank = 8、α = 32、dropout = 0.1,BF16,`gradient_accumulation_steps=16`、`qlen=512`)以及与微调阶段一致的 KT 优化规则。我们分别评测了(a)风格化对话的迁移效果,以及(b)两类具有代表性的**定量基准**:西式翻译腔(生成式)与 AfriMed-QA(医疗垂直领域,含**简答生成**与**单项选择**两种子任务)。固定使用AMX指令集优化;GPU选取2张 48G VRAM 的 RTX 4090,CPU选取 Intel Xeon Platinum 8488C。
|
||||
|
||||
### 效果测试
|
||||
|
||||
#### 风格化对话测试(CatGirl语气)
|
||||
|
||||
数据集采用[NekoQA-10K](https://zhuanlan.zhihu.com/p/1934983798233231689)进行风格迁移微调,目标是提升语气一致性与可辨识度。
|
||||
|
||||
下图展示了原模型与微调后模型的对比。微调后回答在称谓、语气标记与修饰语上更稳定地保持了目标风格(红框),相较原模型的中性与理性表达(蓝框)具有更强的风格可辨识性,说明KT-LoRA 能以较低 GPU 成本,将特定风格特征有效注入到大模型生成分布。
|
||||
|
||||

|
||||
|
||||
#### 生成式翻译风格基准测试
|
||||
|
||||
数据集采用了[西式翻译腔数据集](https://github.com/Benson114/Translational-Style-ChatLLM),要求模型采用夸张的“西式翻译腔”,属生成式风格控制任务,评价指标采用生成任务常见的 BLEU-1/2/3/4 与 ROUGE-1/2/L。
|
||||
|
||||
| 西式翻译腔数据集 | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 20.66 | 8.33 | 4.54 | 2.89 | 22.71 | 4.52 | 19.19 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **35.41** | **22.44** | **15.42** | **11.18** | **42.03** | **18.38** | **33.10** |
|
||||
| V3原模型(不LoRA微调) | 8.49 | 3.34 | 1.62 | 0.96 | 15.91 | 2.55 | 10.07 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **37.02** | **23.70** | **16.21** | **11.49** | **43.43** | **18.96** | **34.54** |
|
||||
|
||||
如上表测试结果所示,在统一流程与放置策略下,**两种规模的模型在微调后均出现一致性增益**,支持“KT 后端 + LoRA 微调”组合在生成式风格控制上的可用性与有效性。同时,说明 KT 的异构放置与算子优化能够稳定支撑风格域的小样本适配。
|
||||
|
||||
#### 医疗垂直领域基准(AfriMed-SAQ/MCQ)
|
||||
|
||||
数据集采用了[AfriMed-QA](https://aclanthology.org/2025.acl-long.96/)数据集(ACL-2025),作为非洲地区医疗领域的专用数据集,具有很强的场景定制特征,包含单选题(MCQ)和简答题(SAQ)两种形式,在本案例中作为垂直领域微调的评估。评估标准上,SAQ 用 BLEU/ROUGE;MCQ 用 Accuracy。
|
||||
|
||||
| AfriMed-QA数据集(简答任务SAQ) | BLEU-1 | BLEU-2 | BLEU-3 | BLEU-4 | ROUGE-1 | ROUGE-2 | ROUGE-L |
|
||||
| ------------------------------- | --------- | --------- | --------- | --------- | --------- | --------- | --------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 13.58 | 11.12 | 9.10 | 7.23 | 22.48 | 7.81 | 11.73 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **35.90** | **27.63** | **22.99** | **19.15** | **35.25** | **17.50** | **28.44** |
|
||||
| V3原模型(不LoRA微调) | 12.75 | 10.27 | 8.05 | 5.99 | 20.33 | 5.65 | 10.11 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **42.42** | **34.12** | **28.95** | **24.54** | **41.97** | **22.37** | **33.28** |
|
||||
|
||||
| AfriMed-QA数据集(单选任务MCQ) | Accuracy |
|
||||
| ------------------------------- | ---------- |
|
||||
| V2-Lite原模型(不LoRA微调) | 0.0645 |
|
||||
| **KT-LoRA微调DeepSeek-V2-Lite** | **0.4812** |
|
||||
| V3原模型(不LoRA微调) | 0.5833 |
|
||||
| **KT-LoRA微调DeepSeek-V3** | **0.7930** |
|
||||
|
||||
如上表所示,(1)DeepSeek-V3(671B)经 KT-LoRA 微调后在MCQ和SAQ任务上均明显高于微调后的 DeepSeek-V2-Lite(14B),并且超过 V3 原模型。在我们的小规模设置中,初步说明了KT-LoRA微调巨大参数模型,在垂直领域中具有实际意义。
|
||||
|
||||
(2)在 SAQ/MCQ 两类子任务上,KT-LoRA 均带来一致增益,说明在 KT 的异构放置与后端算子支持下,LoRA 微调能够把“医疗等垂直领域的知识要点”有效注入模型。
|
||||
|
||||
#### 局限性说明
|
||||
|
||||
目前我们基于的多为单数据集、小规模(2w条及以下)进行测试,旨在提供**KT-LoRA微调系统有效性的“存在性证据”**,而非对算法泛化或规模规律的概括性结论。我们报告中主要给出的是代表性数值;若要支持更强的算法结论,需要更大样本、跨语种/跨域多数据集与多随机种子重复实验,本文不作展开。
|
||||
|
||||
**我们也特别欢迎大家加入LLaMA-Factory KT微调的开源项目中,如果大家有更多的测试结果,也特别特别欢迎写在下面的共享表格中,并补充好`kt_optimize_rule` 文件、数据集example、训练/评测 YAML、具体显存与 CPU 配置等,以便大家参考、复现~!**
|
||||
|
||||
|
||||
|
||||
### 速度测试
|
||||
|
||||
#### 端到端性能
|
||||
|
||||
**测试定义:**
|
||||
|
||||
`step_time`:一次优化步的总耗时(含张量搬运、Attention、MoE 等全部计算)。
|
||||
|
||||
`tokens_per_step = GAS × qlen`;`token/s = tokens_per_step / step_time`。 本节统一采用 `GAS=16`、`qlen=512`,因此 `tokens_per_step = 8192`。
|
||||
|
||||
**实测结果:**
|
||||
|
||||
| 模型 | step_time (s) | tokens/step | token/s |
|
||||
| -------------------- | ------------- | ----------- | --------- |
|
||||
| DeepSeek-V3-671B | 203 | 8192 | **40.35** |
|
||||
| DeepSeek-V2-Lite-14B | 36 | 8192 | **227.6** |
|
||||
|
||||
#### MoE部分的计算性能(DeepSeek-V3-671B)
|
||||
|
||||
**理论估算**
|
||||
|
||||
- MoE 每层、每token的前/反向浮点计算总量 (FLOPs) 可近似:
|
||||
$$
|
||||
\text{FLOPs}_{\text{per-layer, per-token}} \approx c \cdot k \cdot H \cdot I
|
||||
$$
|
||||
|
||||
其中:$k = 8$(Top-k 专家数),$H = 7168$(hidden size),$I = 2048$(intermediate size),常数 $c\approx16$(折合前向=6、反向=10 的矩阵乘总系数)。
|
||||
|
||||
- 每步(全 MoE 层)FLOPs 近似:
|
||||
$$
|
||||
\text{FLOPs}_{\text{per-step}} \approx c \cdot qlen \cdot k \cdot H \cdot I \cdot L_{\text{MoE}}
|
||||
$$
|
||||
|
||||
代 $c=16, qlen=512, k=8, H=7168, I=2048, L_{MoE}=58$,得 $\text{FLOPs}_{\text{per-step}} \approx 55.8\ \text{TFLOPs}$.
|
||||
|
||||
**实测情况**
|
||||
|
||||
MOE部分在CPU上面的性能情况:每秒浮点计算量 $\text{TFLOPS} = \text{FLOPs}_{\text{per-step}} / \text{step\_per\_second}.$
|
||||
|
||||
| TFLOPS | Forward | Backward |
|
||||
| ---------------------- | ------- | -------- |
|
||||
| 平均值(单位:TFLOPS) | 17.55 | 18.41 |
|
||||
|
||||
### 显存/内存性能
|
||||
|
||||
DeepSeek-V3(671B,61层,其中58层有MoE)占用显存大约70GB(多卡总量)、内存占用约1.2-1.3TB。
|
||||
|
||||
DeepSeek-V2-lite(14B,27层,其中26层有MoE)占用显存大约5GB、内存占用约30GB。
|
||||
|
||||
|
||||
|
||||
## 结论
|
||||
|
||||
通过将 KTransformers LoRA 微调集成到 LLaMA‑Factory,我们为希望高效训练和部署 MoE 大模型的用户提供了一条可行路径。KT 提供新的放置策略和算子优化(支持 DeepSeek、Qwen、Kimi 等模型,并结合 AMX 指令加速关键内核),配合 LoRA 微调实现了在极低 GPU 显存占用下的模型定制化训练;而 LLaMA‑Factory 则提供了友好的上层接口与配置管理,让这一切变得易于使用。
|
||||
|
||||
这种集成意味着即便是拥有数百亿乃至上万亿参数的 MoE 模型,也能够在相对普通的硬件上完成微调,并进行低延迟的推理部署。**显存节省**、**速度提升**和**易用性**在这套方案中达到了一定的平衡。我们期待社区在未来的 MoE 项目中尝试使用 LLaMA‑Factory 与 KTransformers 的组合,并欢迎参考本文档提供的指南进行操作。通过这一方案,超大模型不再是“无法企及”的存在,而成为每个开发者都可能驾驭的工具。
|
||||