-
Notifications
You must be signed in to change notification settings - Fork 10
add guides section and fine-tuning overview #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a69930
4a4cccf
da52a86
e4a7326
4e27be5
393a0b2
9b351cd
fccb2ad
5c23efc
36025e4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| --- | ||
| title: "Hardware Evaluation" | ||
| description: "Profile Liquid Foundation Models for latency, throughput, and memory on your target hardware." | ||
| --- | ||
|
|
||
| Use this guide when you are evaluating LFMs on a specific board, accelerator, mobile device, or server. The goal is to measure latency, throughput, memory behavior, and quantization trade-offs on the hardware you plan to ship. | ||
|
Check warning on line 6 in guides/hardware-evaluation.mdx
|
||
|
|
||
| ## Recommended models | ||
|
|
||
| Start with **LFM2.5-350M**. It is small enough to bring up quickly on almost any target and is the first model many silicon partners profile. | ||
|
|
||
| Then scale through the family to map the performance curve: | ||
|
|
||
| 1. **LFM2.5-350M**: bring-up and baseline | ||
| 2. **LFM2.5-1.2B-Instruct**: standard dense datapoint | ||
|
Check warning on line 15 in guides/hardware-evaluation.mdx
|
||
| 3. **LFM2.5-8B-A1B**: MoE with 1.5B active parameters, useful for testing sparse-model behavior on your memory subsystem | ||
| 4. **LFM2.5-VL-450M** and **LFM2.5-Audio-1.5B**: multimodal datapoints when your target supports vision or audio workloads | ||
|
Check warning on line 17 in guides/hardware-evaluation.mdx
|
||
|
|
||
| The LFM2 and LFM2.5 architecture interleaves short convolutions with grouped-query attention. In practice, that means less KV-cache pressure and better long-context latency scaling than pure-attention models of the same size. Your profiling should make that behavior visible. | ||
|
|
||
| ## Setup by framework | ||
|
|
||
| | Framework | Guide | Typical target | | ||
| | --- | --- | --- | | ||
| | Transformers | [Transformers](/deployment/gpu-inference/transformers) | GPU baseline, correctness check | | ||
| | vLLM | [vLLM](/deployment/gpu-inference/vllm) | GPU serving | | ||
| | SGLang | [SGLang](/deployment/gpu-inference/sglang) | GPU serving | | ||
|
Check warning on line 27 in guides/hardware-evaluation.mdx
|
||
| | llama.cpp | [llama.cpp](/deployment/on-device/llama-cpp) | CPU, embedded, custom silicon | | ||
| | Ollama | [Ollama](/deployment/on-device/ollama) | Local development | | ||
|
Check warning on line 29 in guides/hardware-evaluation.mdx
|
||
| | MLX | [MLX](/deployment/on-device/mlx) | Apple Silicon | | ||
| | ONNX | [ONNX](/deployment/on-device/onnx) | NPUs and accelerator toolchains | | ||
|
Check warning on line 31 in guides/hardware-evaluation.mdx
|
||
| | LEAP SDK | [Quick Start](/deployment/on-device/sdk/quick-start) | iOS and Android apps | | ||
|
|
||
| For most silicon evaluations, **llama.cpp with GGUF** or **ONNX** is the fastest path to numbers on your target. | ||
|
|
||
| ## Quantization | ||
|
|
||
| LFMs are routinely deployed quantized on device. Major models ship pre-quantized, so choose the quantization level that fits your memory budget. Lower precision reduces memory and usually improves throughput. | ||
|
Check warning on line 38 in guides/hardware-evaluation.mdx
|
||
|
|
||
| - **GGUF ladder:** `Q4_0`, `Q4_K_M`, `Q5_K_M`, `Q6_K`, `Q8_0`, `F16` | ||
| - **MLX:** 4-bit, 5-bit, 6-bit, 8-bit, and bf16 repos per model | ||
|
Check warning on line 41 in guides/hardware-evaluation.mdx
|
||
| - **ONNX:** per-model `-ONNX` repos | ||
|
Check warning on line 42 in guides/hardware-evaluation.mdx
|
||
|
|
||
| `Q4_K_M` is the default recommendation for CPU and edge deployments. Move up the ladder if your quality bar requires it. | ||
|
|
||
| Profile at least two quantization levels, such as `Q4_K_M` and `Q8_0`, so you can see the memory, quality, and throughput trade-off on your hardware instead of measuring only one point. | ||
|
|
||
| ## Benchmarking methodology | ||
|
|
||
| Report end-to-end latency with prefill and decode separated: | ||
|
Check warning on line 50 in guides/hardware-evaluation.mdx
|
||
|
|
||
| - Time to first token | ||
| - Decode tokens per second | ||
| - P50 and P95 latency, after one warmup iteration | ||
|
|
||
| Use these prompt and output lengths: | ||
|
|
||
| | Input tokens | Output tokens | | ||
| | --- | --- | | ||
| | 256 | 100 | | ||
| | 512 | 100 | | ||
| | 1024 | 100 | | ||
|
|
||
| Report peak memory at each context length: | ||
|
|
||
| - 256 tokens | ||
| - 512 tokens | ||
| - 1024 tokens | ||
| - 2048 tokens | ||
| - 4096 tokens | ||
|
|
||
| This gives you a clear view of scaling behavior, KV-cache efficiency, and deployment headroom. | ||
|
|
||
| ## Related docs | ||
|
|
||
| - [Complete Model Library](/lfm/models/complete-library) | ||
| - [Use Case Evaluation](/guides/use-case-evaluation) | ||
| - [Migration Guide](/guides/migration-guide) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,242 @@ | ||
| --- | ||
| title: "Migration Guide" | ||
| description: "Move from Qwen, Llama, or Gemma to LFMs while avoiding the common migration pitfalls." | ||
|
Check warning on line 3 in guides/migration-guide.mdx
|
||
| --- | ||
|
|
||
| This guide is for teams already running Qwen, Llama, or Gemma who want to evaluate Liquid Foundation Models as replacements. LFMs load and serve through the same frameworks you already use, so most migrations are a model ID and config change. The details that usually matter are sampling defaults, chat templates, tool-call parsing, and LoRA module names. | ||
|
Check warning on line 6 in guides/migration-guide.mdx
|
||
|
|
||
| Use this alongside [Use Case Evaluation](/guides/use-case-evaluation) for model selection and benchmarking methodology. | ||
|
|
||
| ## Model mapping | ||
|
|
||
| Pick the LFM in the same deployment class as your current model. Compare within class; benchmarking a 1.2B LFM against a 32B Qwen does not tell you whether it fits your deployment. | ||
|
Check warning on line 12 in guides/migration-guide.mdx
|
||
|
|
||
| | If you run | Evaluate | Notes | | ||
| | --- | --- | --- | | ||
| | Qwen3-0.6B, Llama-3.2-1B, Gemma-3-270M/1B | [LFM2.5-350M](https://huggingface.co/LiquidAI/LFM2.5-350M) | Classification, extraction, routing. Also consider LFM2.5-230M. | | ||
| | Qwen3-1.7B, Llama-3.2-3B, Gemma-3-4B | [LFM2.5-1.2B-Instruct](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Instruct) | The default dense workhorse. | | ||
| | Qwen3-4B/8B, Llama-3.1-8B, Gemma-3-12B | [LFM2.5-8B-A1B](https://huggingface.co/LiquidAI/LFM2.5-8B-A1B) | MoE with 8B total and 1.5B active parameters. | | ||
| | Qwen3-14B/32B and larger dense models | [LFM2-24B-A2B](https://huggingface.co/LiquidAI/LFM2-24B-A2B) | 24B total and roughly 2.3B active parameters. | | ||
| | Qwen3 thinking mode or DeepSeek distills | [LFM2.5-1.2B-Thinking](https://huggingface.co/LiquidAI/LFM2.5-1.2B-Thinking) | Reasoning traces at 1.2B. | | ||
| | Qwen2.5-VL-3B/7B, Llama-3.2-Vision, Gemma-3 vision | [LFM2.5-VL-450M](https://huggingface.co/LiquidAI/LFM2.5-VL-450M) or [LFM2.5-VL-1.6B](https://huggingface.co/LiquidAI/LFM2.5-VL-1.6B) | Use `-Extract` variants for image to strict JSON. | | ||
| | Whisper plus separate TTS | [LFM2.5-Audio-1.5B](https://huggingface.co/LiquidAI/LFM2.5-Audio-1.5B) | ASR, TTS, and speech-to-speech in one model. | | ||
|
|
||
| See the [Complete Model Library](/lfm/models/complete-library) for the full catalog. | ||
|
|
||
| LFM2.5 dense models support 32K context, and LFM2.5-8B-A1B supports 128K. If you rely on 128K context in a small dense Qwen or Llama model, check your production context distribution before assuming this is a blocker. Most sub-8B deployments do not exceed 8K tokens. | ||
|
Check warning on line 26 in guides/migration-guide.mdx
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Too model-specific, too hard to maintain. |
||
|
|
||
| ## Runtime-by-runtime migration | ||
|
|
||
| Minimum versions: | ||
|
|
||
| - `transformers >= 5.2.0` | ||
| - vLLM `>= 0.23.0` | ||
|
|
||
| <Tabs> | ||
| <Tab title="Transformers"> | ||
| Change the model ID and use the model's chat template: | ||
|
|
||
| ```python | ||
| from transformers import AutoModelForCausalLM, AutoTokenizer | ||
|
|
||
| model_id = "LiquidAI/LFM2.5-1.2B-Instruct" | ||
| model = AutoModelForCausalLM.from_pretrained( | ||
| model_id, | ||
| dtype="bfloat16", | ||
| device_map="auto", | ||
| ) | ||
| tokenizer = AutoTokenizer.from_pretrained(model_id) | ||
|
|
||
| inputs = tokenizer.apply_chat_template( | ||
| [{"role": "user", "content": "What is C. elegans?"}], | ||
| add_generation_prompt=True, | ||
| return_tensors="pt", | ||
| return_dict=True, | ||
| ).to(model.device) | ||
|
|
||
| out = model.generate( | ||
| **inputs, | ||
| max_new_tokens=512, | ||
| do_sample=True, | ||
| temperature=0.1, | ||
| top_k=50, | ||
| repetition_penalty=1.05, | ||
| ) | ||
| ``` | ||
|
|
||
| Do not reuse literal Llama-style or Gemma-style prompt strings. They will usually run, but quality will degrade. | ||
|
|
||
| See [Transformers](/deployment/gpu-inference/transformers). | ||
| </Tab> | ||
|
|
||
| <Tab title="vLLM"> | ||
| Serve the model behind an OpenAI-compatible endpoint: | ||
|
|
||
| ```bash | ||
| vllm serve LiquidAI/LFM2.5-1.2B-Instruct | ||
| ``` | ||
|
|
||
| Your OpenAI-client code stays mostly unchanged: | ||
|
|
||
| ```python | ||
| client.chat.completions.create( | ||
| model="LiquidAI/LFM2.5-1.2B-Instruct", | ||
| messages=messages, | ||
| temperature=0.1, | ||
| extra_body={"top_k": 50, "repetition_penalty": 1.05}, | ||
| ) | ||
| ``` | ||
|
|
||
| If you use OpenAI-style `tools=[...]`, configure the LFM tool-call parser before switching traffic. See [Tool calling](#tool-calling) below and the [vLLM guide](/deployment/gpu-inference/vllm). | ||
| </Tab> | ||
|
|
||
| <Tab title="SGLang"> | ||
| Serve the model through SGLang's OpenAI-compatible API and keep your client integration mostly unchanged: | ||
|
Check warning on line 94 in guides/migration-guide.mdx
|
||
|
|
||
| ```bash | ||
| sglang serve --model-path LiquidAI/LFM2.5-1.2B-Instruct --tool-call-parser lfm2 | ||
| ``` | ||
|
|
||
| Use LFM sampling defaults and configure the LFM tool-call parser if your evaluation includes tools. | ||
|
|
||
| See [SGLang](/deployment/gpu-inference/sglang). | ||
| </Tab> | ||
|
|
||
| <Tab title="llama.cpp"> | ||
| Pull the official GGUF and choose the quantization level you plan to deploy: | ||
|
|
||
| ```bash | ||
| llama-server -hf LiquidAI/LFM2.5-1.2B-Instruct-GGUF:Q4_K_M | ||
| ``` | ||
|
|
||
| The GGUF embeds the correct chat template. Do not override it with an old Qwen or Llama template. | ||
|
|
||
| See [llama.cpp](/deployment/on-device/llama-cpp). | ||
| </Tab> | ||
|
|
||
| <Tab title="Ollama / LM Studio"> | ||
| Use the official GGUF artifact and keep the embedded chat template: | ||
|
|
||
| ```bash | ||
| ollama run hf.co/LiquidAI/LFM2.5-1.2B-Instruct-GGUF:Q4_K_M | ||
| ``` | ||
|
|
||
| If you are using LM Studio, select the matching GGUF quantization and avoid overriding the prompt template with a previous Qwen, Llama, or Gemma template. | ||
|
|
||
| See [Ollama](/deployment/on-device/ollama) and [LM Studio](/deployment/on-device/lm-studio). | ||
| </Tab> | ||
|
|
||
| <Tab title="MLX / ONNX"> | ||
| Per-precision repos exist for each model, including `-MLX-4bit` through `-MLX-8bit` and `-ONNX`. Swap the repo ID in `mlx-lm` or your ONNX Runtime pipeline. | ||
|
Check warning on line 130 in guides/migration-guide.mdx
|
||
|
|
||
| See [MLX](/deployment/on-device/mlx) and [ONNX](/deployment/on-device/onnx). | ||
| </Tab> | ||
|
|
||
| <Tab title="LEAP SDK"> | ||
| The [LEAP SDK](/deployment/on-device/sdk/quick-start) gives iOS and Android apps a supported runtime with function calling and constrained generation included. | ||
| </Tab> | ||
| </Tabs> | ||
|
Comment on lines
+35
to
+138
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should really reuse existing code blocks instead of re-writing them here because it will be a nightmare to maintain |
||
|
|
||
| ## Chat template and sampling | ||
|
|
||
| LFMs use a ChatML-style format: | ||
|
Check warning on line 142 in guides/migration-guide.mdx
|
||
|
|
||
| ```text | ||
| <|startoftext|><|im_start|>system | ||
| You are a helpful assistant trained by Liquid AI.<|im_end|> | ||
| <|im_start|>user | ||
| What is C. elegans?<|im_end|> | ||
| <|im_start|>assistant | ||
| ``` | ||
|
|
||
| Roles are `system`, `user`, `assistant`, and `tool`. Vision-language models use an `<image>` sentinel. See [Chat template](/lfm/key-concepts/chat-template). | ||
|
|
||
| Migration notes: | ||
|
|
||
| - **From Qwen:** ChatML is familiar, but token details differ. Use `apply_chat_template`; do not reuse literal Qwen strings. | ||
|
Check warning on line 156 in guides/migration-guide.mdx
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggest adding a link to HF here like https://huggingface.co/docs/transformers/main/en/chat_templating#using-applychattemplate |
||
| - **From Llama:** replace `<|begin_of_text|>` and `<|start_header_id|>` prompt builders. | ||
| - **From Gemma:** replace `<start_of_turn>` builders. LFMs support a real `system` role. | ||
|
Check warning on line 158 in guides/migration-guide.mdx
|
||
|
|
||
| Recommended starting sampling values: | ||
|
|
||
| | Param | LFM2.5 recommendation | Common carry-over mistake | | ||
|
Check warning on line 162 in guides/migration-guide.mdx
|
||
| | --- | --- | --- | | ||
| | `temperature` | `0.1` | `0.6` to `0.7`, which can cause drift | | ||
| | `top_k` | `50` | disabled | | ||
| | `repetition_penalty` | `1.05` | `1.0` | | ||
|
Comment on lines
+164
to
+166
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Our gen parameters are actually model-specific so it's not correct :( |
||
|
|
||
| For deterministic classification, extraction, and structured output, use greedy decoding. See [Text generation and prompting](/lfm/key-concepts/text-generation-and-prompting). | ||
|
|
||
| ## Tool calling | ||
|
|
||
| LFMs natively emit a Pythonic tool-call list, not OpenAI-style JSON: | ||
|
Check warning on line 172 in guides/migration-guide.mdx
|
||
|
|
||
| ```text | ||
| <|tool_call_start|>[get_candidate_status(candidate_id="12345")]<|tool_call_end|> | ||
| ``` | ||
|
|
||
| If you swap an agent to an LFM and let a generic JSON parser run, tool calls can appear broken. The format is different. | ||
|
|
||
| What to do: | ||
|
|
||
| 1. Pass tools through `tokenizer.apply_chat_template(messages, tools=[...])` or the serving runtime's supported tool mechanism. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also maybe link it to the relevant section in apply_chat_template() |
||
| 2. Parse the Pythonic call list between `<|tool_call_start|>` and `<|tool_call_end|>`. | ||
|
Check warning on line 183 in guides/migration-guide.mdx
|
||
| 3. On vLLM or SGLang, configure the LFM tool-call parser instead of a generic JSON parser. | ||
|
Check warning on line 184 in guides/migration-guide.mdx
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the correct name is "lfm2" (to verify) |
||
| 4. Return results as `tool` role messages, with JSON content if useful. | ||
| 5. For strict schemas, use constrained decoding. See [Constrained Generation](/deployment/on-device/sdk/constrained-generation). | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure this is worth mentioning here |
||
| 6. If you fine-tune for tool calling, train on the native Pythonic format and convert to any internal DSL after parsing. | ||
|
Check warning on line 187 in guides/migration-guide.mdx
|
||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DSL is never defined 👀 |
||
|
|
||
| ## Migrating your fine-tuning pipeline | ||
|
|
||
| LFMs are standard Hugging Face causal LMs, so TRL and Unsloth-style pipelines carry over with two LFM-specific corrections. | ||
|
Check warning on line 191 in guides/migration-guide.mdx
|
||
|
|
||
| First, update LoRA `target_modules`. LFM2 and LFM2.5 use a conv-attention hybrid with different module names than Llama-family models: | ||
|
|
||
| ```python | ||
| # LFM2 / LFM2.5 | ||
| target_modules = ["w1", "w2", "w3", "q_proj", "k_proj", "v_proj", "out_proj", "in_proj"] | ||
|
|
||
| # Llama/Qwen/Gemma configs are wrong for LFMs: | ||
| # o_proj/gate_proj/up_proj/down_proj do not exist. | ||
| ``` | ||
|
|
||
| Before a long run, call `model.print_trainable_parameters()`. You should see millions of trainable parameters, and the LoRA module count should be in the expected range for your model size. If it is near zero, the module names are wrong. | ||
|
|
||
| Second, format training examples with the LFM chat template. Training data formatted with your previous model's template creates a silent distribution mismatch. | ||
|
|
||
| Everything else transfers directly: | ||
|
|
||
| - [LEAP Finetune](https://github.com/Liquid4All/leap-finetune) for SFT, LoRA, DPO, GRPO, text, VLM, MoE, local, SLURM, Kubernetes, Modal, and GGUF export workflows | ||
| - Existing [TRL](/lfm/fine-tuning/trl) or [Unsloth](/lfm/fine-tuning/unsloth) setups | ||
| - Starting LoRA recipe: `r=16`, `alpha=32`, learning rate around `2e-4` to `3e-4`, 3 to 5 epochs, bf16 | ||
|
|
||
| ## Migration checklist | ||
|
|
||
| ### Serving swap | ||
|
|
||
| - Runtime meets minimum version requirements | ||
| - Model ID swapped | ||
| - Chat template comes from the model | ||
| - Sampling updated for LFM defaults | ||
| - Tool parser configured if tool calling is in scope | ||
| - Context length validated against production p95 | ||
|
|
||
| ### Evaluation | ||
|
|
||
| - Comparison stays within the same deployment class | ||
| - Latency and throughput measured at production prompt lengths and concurrency | ||
| - Quantized artifact evaluated if you plan to ship quantized | ||
|
|
||
| ### Fine-tuning | ||
|
|
||
| - LoRA `target_modules` updated to LFM names | ||
| - Trainable-parameter count sanity-checked | ||
| - Training data reformatted with the LFM chat template | ||
| - Tool-call training data uses the native Pythonic format | ||
|
Check warning on line 235 in guides/migration-guide.mdx
|
||
| - Held-out eval set frozen before training | ||
|
Check warning on line 236 in guides/migration-guide.mdx
|
||
|
|
||
| ## Related docs | ||
|
|
||
| - [Hardware Evaluation](/guides/hardware-evaluation) | ||
| - [Use Case Evaluation](/guides/use-case-evaluation) | ||
| - [Fine-tuning Overview](/lfm/fine-tuning/overview) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is super accurate. I would bundle the 230M and 350M together. Same with 1.2B Instruct and Thinking (just depends on the acceptable latency). Same with the 2.6B and 8B-A1B.