LFM2.5

LFM2.5

LFM2.5는 Liquid AI의 온디바이스 배포용 하이브리드 모델 제품군으로, LFM Open License v1.0로 공개됐어요. LFM2 아키텍처를 확장한 사전학습(dense 모델은 10T → 28T 토큰, 8B-A1B MoE는 12T → 38T 토큰)과 대규모 강화 학습을 기반으로 해요. 이 제품군은 적은 수의 GQA 블록과 gated short convolution 블록을 인터리브한 하이브리드 구조로, 엣지 지연 시간·메모리 예산에서 CPU에서도 비슷한 크기 모델보다 최대 2배 빠른 prefill·decode를 제공해요.

출처: 문서

본문

1. Model Introduction

LFM2.5는 Liquid AI의 온디바이스 배포용 하이브리드 모델 제품군으로, LFM Open License v1.0로 공개됐어요. LFM2 아키텍처에 확장된 사전학습(dense 모델 10T → 28T 토큰, 8B-A1B MoE 12T → 38T 토큰)과 대규모 강화 학습을 적용했어요.

백본은 gated short convolution 블록과 소수의 grouped query attention (GQA) 블록을 인터리브해요. 각 convolution 블록은 depthwise short convolution 주변에 입력 의존적 곱셈 게이팅을 적용해서 낮은 연산·메모리 비용으로 빠른 로컬 믹싱을 제공해요. GQA 블록은 전역 컨텍스트와 장문 검색을 처리해요.

이 최소 하이브리드 배치는 엣지 지연 시간과 메모리 예산 하에서 hardware-in-the-loop 아키텍처 탐색으로 선택됐어요. CPU에서는 비슷한 크기 모델보다 최대 2배 빠른 prefill과 decode를 제공해요(LFM2 Technical Report 참조).

주요 특징:

  • 하이브리드 gated short conv + GQA 배치: 1.2B / 350M dense 모델은 16 레이어(10 conv + 6 GQA); 8B-A1B MoE는 24 레이어(18 conv + 6 GQA). 모델당 어텐션 레이어가 6개뿐이라 긴 컨텍스트에서도 KV cache가 작게 유지돼요.
  • 블록 세부: kernel size 3의 depthwise convolution; 8 KV 그룹·head size 64·RoPE·QK-Norm의 GQA; 전역에 pre-norm RMSNorm과 SwiGLU MLP.
  • Sparse MoE (8B-A1B): 총 8.3B / 활성 1.5B 파라미터. 처음 두 레이어를 제외한 모든 레이어가 dense MLP를 32-전문가 MoE 블록으로 교체; 각 토큰은 정규화된 sigmoid router(적응형 bias 로드 밸런싱 포함)로 top-4 SwiGLU 전문가에 라우팅돼요.
  • 2.5의 새로운 점 (8B-A1B): 블록은 LFM2-8B-A1B와 동일하지만 컨텍스트 윈도우가 32K에서 128K로 늘어나고(RoPE base-θ 증가 + long-context midtraining) 어휘가 65,536에서 128,000 토큰으로 두 배가 되어 비라틴계 토큰화가 더 효율적이에요.
  • Pythonic tool calling: 함수 호출이 <|tool_call_start|><|tool_call_end|> 토큰 사이의 Python 리스트로 출력돼요. lfm2 tool-call parser가 이를 표준 message.tool_calls로 표면화해요.
  • Reasoning 변형: 8B-A1B와 1.2B-Thinking 체크포인트는 답보다 먼저 명시적 chain-of-thought를 항상 내보내는 reasoning 전용 모델이에요. MoE의 1.5B 활성 파라미터는 그 reasoning 토큰을 저렴하게 유지해요.
  • 다국어: JP 체크포인트를 제외한 모든 모델이 최소 영어·아랍어·중국어·프랑스어·독일어·일본어·한국어·스페인어를 다뤄요(일부 변형은 더 추가). 전용 JP 채팅 체크포인트는 일본어(일본어 + 영어만)에 집중해요.
  • 비전: LFM2.5-VL-1.6B는 1.2B 언어 백본을 SigLIP2 So400M NaFlex 인코더와 짝지어 OCR·문서 이해·다국어 비전을 지원해요. LFM2.5-VL-450M은 350M 백본에 SigLIP2 Base-86M 인코더를 짝지어 엣지 크기의 캡셔닝·객체 검출을 지원해요; bounding-box grounding과 function calling은 2.5 릴리스에서 새로 추가됐어요.

이용 가능한 모델:

Model Parameters Context Role
LFM2.5-8B-A1B 8.3B total / 1.5B active (MoE) 128K Reasoning-tuned, agentic / tool use
LFM2.5-1.2B-Instruct 1.17B (dense) 32K General instruct, RAG, data extraction
LFM2.5-1.2B-Thinking 1.17B (dense) 32K Reasoning (always-on chain-of-thought)
LFM2.5-350M 350M (dense) 32K Compact instruct, structured output
LFM2.5-230M 230M (dense) 32K Most compact; data extraction, structured output
LFM2.5-1.2B-JP-202606 1.17B (dense) 32K Japanese chat (latest)
LFM2.5-1.2B-JP 1.17B (dense) 32K Japanese chat (original)
LFM2.5-VL-1.6B 1.2B LM + SigLIP2 400M 32K Vision-language (OCR, docs, multi-image)
LFM2.5-VL-450M 350M LM + SigLIP2 86M 32K Compact vision-language (captioning, object detection)
LFM2.5-1.2B-Base 1.17B (dense) 32K Pre-trained base (no post-training)

위 Deploy 패널은 여덟 개 서빙 변형을 다뤄요; LFM2.5-1.2B-JP(원본 — --tool-call-parser 없이 시작)와 Base 저장소(사전학습 전용, 후학습 없음 — §3.5 참조)는 모델 경로만 바꿔 같은 방식으로 시작해요.

변형 선택:

  • 8B-A1B — agentic·tool-calling 워크로드의 플래그십; 유일한 128K-컨텍스트 옵션.
  • 1.2B-Thinking — reasoning 중심 작업: 수학, tool 사용, 프로그래밍.
  • 1.2B-Instruct — 채팅과 창작 글쓰기에 권장.
  • 350M — tool 사용, 데이터 추출, 구조화 출력; 수학·코드·창작 글쓰기에는 비권장.
  • 230M — 가장 컴팩트한 체크포인트; 350M과 같은 용도, 수학·코드·창작 글쓰기용 아님.

라이선스: LFM Open License v1.0.

리소스: LFM2.5 announcement, LFM2.5-8B-A1B blog, LFM docs, LFM2 Technical Report (arXiv:2511.23404).

2. Configuration Tips

  • Reasoning parser: LFM2.5 reasoning 모델은 chain-of-thought를 thinking... response 태그로 감싸요. 명령 생성기는 8B-A1B용으로 --reasoning-parser qwen3(명시적 시작 thinking 출력)를, 1.2B-Thinking용으로 --reasoning-parser qwen3-thinking(상시 reasoning)를 전달해요. 이는 thinking 과정을 reasoning_content로 분리하며, 없으면 chain-of-thought가 content에 인라인으로 남아요.
  • Tool calling: --tool-call-parser lfm2는 LFM2.5의 Pythonic <|tool_call_start|>[...]<|tool_call_end|> 호출을 표준 message.tool_calls로 표면화해요. 원본 1.2B-JP는 tool calling을 노출하지 않으며, Base는 후학습이 없어요(§3.5 참조).
  • Blackwell (B200/sm100)의 어텐션 백엔드: SGLang은 sm100에서 trtllm_mha 백엔드를 기본으로 하며, dense 텍스트 모델에 가장 빠르다. 8B-A1B는 page-size-1 백엔드에서 동작하는 mamba-style 상태 캐시를 사용하므로 생성기는 --attention-backend flashinfer를 선택해요. VL 언어 모델도 같은 상태 캐시를 사용하며 두 백엔드를 제공해요: --attention-backend flashinfer(prefix/radix 캐싱 유지 — 생성기가 내보내는 것), 또는 --attention-backend trtllm_mha --disable-radix-cache(Blackwell trtllm_mha 어텐션에서 언어 모델 실행 — --disable-radix-cache는 page-size-1 요구를 풀지만 prefix 캐싱을 희생). 둘 다 비전 타워용 --mm-attention-backend fa4와 짝지을 수 있어요.
  • VL 비전 타워 (--mm-attention-backend): sm100에서 trtllm_mha 기본값은 텍스트에 가장 빠르지만 이미지 토큰에 causal 어텐션을 적용해요. VL 모델에서는 B200/B300에 --mm-attention-backend fa4(또는 H100/H200에 fa3)를 전달해 양방향 이미지 토큰 어텐션과 전체 비전 품질을 복원해요.
  • VL 멀티모달 피처 전송: 생성기는 VL 모델을 SGLANG_USE_CUDA_IPC_TRANSPORT=1 SGLANG_USE_IPC_POOL_HANDLE_CACHE=1로 시작해요. 첫 번째는 processor→scheduler 이미지 피처 핸드오프를 프로세스 간 텐서 직렬화 대신 CUDA IPC로 옮기고, 두 번째는 pool 핸들을 전달해 scheduler가 요청마다 per-item 핸들을 여는 대신 한 번 열고 캐시하게 해요. 이미지 서빙 워크로드(1 이미지 @ 720p, VL-1.6B에서 H100과 B200으로 측정)에서 이 쌍은 없을 때보다 약 30–50% 더 높은 이미지 처리량과 30–40% 더 낮은 이미지 TTFT를 내며(VL-1.6B, H100·B200에서 측정), 디코드 속도(TPOT)는 영향이 없어요.
  • VL-450M 메모리 헤드룸 (--mem-fraction-static 0.8): 기본 메모리 분율로는 450M의 작은 가중치 때문에 SGLang이 정적 KV/mamba 풀을 GPU의 거의 전체로 잡아 이미지 피처 텐서용 헤드룸이 남지 않아요 — 지속적인 동시 이미지 로드에서 scheduler가 radix-cache free 경로에서 CUDA OOM으로 충돌할 수 있어요. 생성기는 VL-450M에 --mem-fraction-static 0.8으로 제한해요; 그래도 풀은 이 모델이 필요한 것보다 훨씬 크다.
  • Mamba 스케줄링: LFM2.5는 기본 no_buffer mamba 스케줄러 전략으로 실행되며 --mamba-radix-cache-strategy 플래그가 필요 없어요. extra_buffer 전략(일부 Gated-DeltaNet 하이브리드에 사용 가능한 overlap-scheduling 처리량 최적화)은 convolution 블록이 mamba_chunk_size=1을 쓰는 LFM2.5에는 적용되지 않아요.
  • 하드웨어 요구사항: 모든 LFM2.5 모델은 Hopper 또는 Blackwell의 단일 GPU(TP=1)에서 실행돼요. 1.2B / 350M dense 모델은 몇 GB에 맞고, 8B-A1B MoE는 bf16 가중치 + KV cache에 약 16 GB가 필요해요. 어떤 변형에도 다중 GPU 텐서 병렬화는 필요하지 않아요.

권장 샘플링 파라미터 — 매 요청에 명시적으로 전달하세요. 일부 LFM2.5 체크포인트는 generation_config.json에 샘플링 기본값을 배포하지 않아서 서버가 대신 적용해주지 않아요. top_k, min_p, repetition_penalty는 표준 OpenAI chat.completions 필드가 아니므로 **extra_body**로 전달하면 SGLang이 sampler로 보내줘요. 출력을 제한하려는 게 아니라면 max_tokens를 설정하지 마세요 — 응답(또는 reasoning 모델의 chain-of-thought)을 도중에 잘라낼 수 있어요.

Model temperature extra_body (sampler)
LFM2.5-8B-A1B 0.2 {"top_k": 80, "repetition_penalty": 1.05}
LFM2.5-1.2B-Instruct 0.1 {"top_k": 50, "repetition_penalty": 1.05}
LFM2.5-1.2B-Thinking 0.05 {"top_k": 50, "repetition_penalty": 1.05}
LFM2.5-350M 0.1 {"top_k": 50, "repetition_penalty": 1.05}
LFM2.5-230M 0.1 {"top_k": 50, "repetition_penalty": 1.05}
LFM2.5-1.2B-JP-202606 0.1 {"top_k": 50, "repetition_penalty": 1.05}
LFM2.5-1.2B-JP 0.3 {"min_p": 0.15, "repetition_penalty": 1.05}
LFM2.5-VL-1.6B (text) 0.1 {"min_p": 0.15, "repetition_penalty": 1.05}
LFM2.5-VL-450M (text) 0.1 {"min_p": 0.15, "repetition_penalty": 1.05}
LFM2.5-1.2B-Base 0.3 {"min_p": 0.15, "repetition_penalty": 1.05}

3. Advanced Usage

3.1 Basic Usage

권장 샘플링 사전설정을 모델별로 적용한 단일 클라이언트(다음 섹션의 예제들은 이 chat 헬퍼를 재사용):

from openai import OpenAI

client = OpenAI(base_url="http://localhost:30000/v1", api_key="EMPTY")

# Non-OpenAI fields (top_k / min_p / repetition_penalty) ride in extra_body.
SAMPLING = {
    "LiquidAI/LFM2.5-8B-A1B":         dict(temperature=0.2,  extra_body={"top_k": 80, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-1.2B-Instruct":  dict(temperature=0.1,  extra_body={"top_k": 50, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-1.2B-Thinking":  dict(temperature=0.05, extra_body={"top_k": 50, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-350M":           dict(temperature=0.1,  extra_body={"top_k": 50, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-230M":           dict(temperature=0.1,  extra_body={"top_k": 50, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-1.2B-JP-202606": dict(temperature=0.1,  extra_body={"top_k": 50, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-VL-1.6B":        dict(temperature=0.1,  extra_body={"min_p": 0.15, "repetition_penalty": 1.05}),
    "LiquidAI/LFM2.5-VL-450M":        dict(temperature=0.1,  extra_body={"min_p": 0.15, "repetition_penalty": 1.05}),
}

def chat(model, messages, **overrides):
    cfg = SAMPLING[model]
    body = cfg["extra_body"] | overrides.pop("extra_body", {})
    return client.chat.completions.create(
        model=model, messages=messages,
        temperature=cfg["temperature"], extra_body=body, **overrides,
    )

resp = chat(
    "LiquidAI/LFM2.5-1.2B-Instruct",
    [{"role": "user", "content": "What is C. elegans? Answer in one sentence."}],
)
print(resp.choices[0].message.content)

3.2 Reasoning

8B-A1B와 1.2B-Thinking 체크포인트는 chain-of-thought를 내장 동작으로 출력해요. Deploy 패널은 일치하는 --reasoning-parser로 시작하는데, 이는 thinking 과정을 reasoning_content로 분리해요:

resp = chat(
    "LiquidAI/LFM2.5-8B-A1B",
    [{"role": "user", "content": "If a train travels 60 km/h for 2.5 hours, how far does it go?"}],
)
msg = resp.choices[0].message
print("Reasoning:", msg.reasoning_content)
print("Answer:", msg.content)

3.3 Tool Calling

LFM2.5는 Pythonic tool call을 작성해요. --tool-call-parser lfm2(이미 시작 명령에 포함)로 표준 message.tool_calls로 표면화돼요:

resp = chat(
    "LiquidAI/LFM2.5-1.2B-Instruct",
    [{"role": "user", "content": "What's the weather in Paris?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a location",
            "parameters": {
                "type": "object",
                "properties": {"location": {"type": "string"}},
                "required": ["location"],
            },
        },
    }],
)
for call in resp.choices[0].message.tool_calls or []:
    print(call.function.name, call.function.arguments)

Tool calling은 8B-A1B, 1.2B-Thinking, 1.2B-Instruct, 350M, 230M, 1.2B-JP-202606, VL-1.6B, VL-450M에서 지원돼요. VL 모델에서는 텍스트 턴 전용이에요 — 같은 턴에 이미지와 tool을 결합하지 마세요.

3.4 Vision Input

VL 모델(VL-1.6B와 VL-450M)은 표준 OpenAI 멀티모달 콘텐츠 블록으로 이미지를 받아요. Base64 data URI(data:image/jpeg;base64,...)가 URL 대신 동작해요:

resp = chat(
    "LiquidAI/LFM2.5-VL-1.6B",
    [{
        "role": "user",
        "content": [
            {"type": "image_url", "image_url": {
                "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg"}},
            {"type": "text", "text": "What is in this image?"},
        ],
    }],
)
print(resp.choices[0].message.content)

3.5 Base Checkpoints

각 크기는 사전학습된 Base 저장소를 배포해요 — LFM2.5-230M-Base, LFM2.5-1.2B-Base, LFM2.5-350M-Base, LFM2.5-8B-A1B-Base — 파인튜닝과 지속 사전학습용이에요.

이 저장소들은 ChatML-스타일 채팅 템플릿을 배포하므로 chat.completions 요청이 정상적으로 포맷돼요. 다만 체크포인트에는 후학습이 없어서 지시 따르기를 기대하지 마세요. raw 텍스트 연속 생성:

comp = client.completions.create(
    model="LiquidAI/LFM2.5-1.2B-Base",
    prompt="The capital of France is",
    temperature=0.3,
    extra_body={"min_p": 0.15, "repetition_penalty": 1.05},
)
print(comp.choices[0].text)