Flama를 사용하여 단일 명령줄로 모든 LLM 서빙하기
요약
Flama 2.0을 사용하여 복잡한 설정 없이 단일 명령줄로 LLM을 다운로드, 패키징 및 서빙하는 방법을 소개합니다. CLI를 통해 HuggingFace 모델을 가져오고, 로컬 상호작용부터 프로덕션용 HTTP API 서빙까지의 전체 워크플로우를 다룹니다.
핵심 포인트
- Flama CLI를 통한 간편한 LLM 다운로드 및 .flm 패키징
- 보일러플레이트 코드 없는 로컬 모델 상호작용 및 스트리밍 지원
- 내장 채팅 인터페이스를 포함한 프로덕션 준비 완료된 HTTP API 서빙
- Claude CLI와 연동하여 로컬 모델 기반 에이전틱 워크플로우 구현 가능
Flama 2.0은 생성형 AI (Generative AI)를 위한 일류 지원을 제공합니다. 이제 대규모 언어 모델 (LLMs)을 다운로드하고, 패키징하며, 서빙하는 것이 터미널에서 몇 가지 명령어를 실행하는 것만큼 간단해졌습니다. 보일러플레이트 (Boilerplate) 코드도, 커스텀 서빙 인프라 (Custom serving infrastructure)도, 설정 파일 (Configuration files)도 필요 없습니다. 오직 CLI와 모델만 있으면 됩니다.
이 포스트에서는 전체 워크플로우를 살펴봅니다: HuggingFace에서 모델을 가져오고, 터미널에서 로컬로 상호작용하며, 프로덕션 준비가 된 API와 내장된 채팅 인터페이스를 통해 HTTP로 모델을 서빙하는 과정입니다. 또한 Claude CLI를 실질적인 예시로 사용하여, 로컬에서 서빙되는 모델이 어떻게 에이전틱 워크플로우 (Agentic workflows)를 구동할 수 있는지 보여드릴 것입니다.
세부 사항을 살펴보기 전에, 다음 리소스들을 준비해 두는 것을 권장합니다:
- 공식 Flama 문서: Flama documentation
- 생성형 AI (Generative AI) 섹션: Generative AI docs
- Flama GitHub 저장소: Flama on GitHub
목차
flama get으로 모델 가져오기- 내부적으로 일어나는 일
- 모델과 로컬에서 상호작용하기
flama model run을 이용한 원샷 쿼리 (One-shot queries)flama model stream을 이용한 스트리밍 응답 (Streaming responses)
- HTTP를 통해 모델 서빙하기
flama serve명령어- 내장된 채팅 인터페이스
- 에이전틱 워크플로우 (Agentic workflows) 구동하기
- 로컬 모델과 함께 Claude CLI 사용하기
- 결론
- 참고 문헌
- 우리의 작업 지원하기
- 저자 소개
flama get으로 모델 가져오기
Flama로 LLM을 서빙하는 첫 번째 단계는 모델을 다운로드하여 .flm 아티팩트 (Flama Lightweight Model 파일)로 패키징하는 것입니다. flama get 명령어는 이 과정을 단일 단계로 처리합니다. 지원되는 소스에서 모델 가중치 (Model weights)와 설정 (Configuration)을 다운로드하고 이를 휴대 가능한 .flm 형식으로 직렬화 (Serialises)합니다.
이 포스트의 모든 예시는 uv를 통해 LLM 엑스트라 (LLM extras)와 함께 Flama가 설치되어 있다고 가정합니다:
uv pip install "flama[llm,pydantic]"
또는, 사전 설치 없이 uvx --from "flama[llm,pydantic]" flama ...를 사용하여 어떤 명령이든 실행할 수도 있지만, 간결함을 위해 Flama가 이미 설치되어 있다고 가정합니다.
MLX Community를 통해 Apple Silicon에 최적화된 Google의 Gemma 4 모델 양자화 (quantised) 버전을 가져와 보겠습니다:
flama get --family llm --source huggingface mlx-community/gemma-4-E2B-it-qat-4bit
Downloading ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 2.3 GB 28.7 MB/s 0:00:00
...
두 가지 옵션이 필요합니다: --source는 Flama가 어디에서 다운로드할지 알려주며 (현재는 HuggingFace), --family는 아티팩트 (artifact)가 전통적인 머신러닝 모델 (ml)인지 생성형 모델 (llm)인지를 선언합니다. 대규모 언어 모델 (Large Language Models)의 경우, 항상 --family llm을 전달합니다.
출력 경로는 슬래시 (slash)가 언더스코어 (underscore)로 대체된 <model-name>.flm을 기본값으로 합니다. 사용자 정의 경로를 선호한다면 --output을 전달하세요:
flama get --family llm --source huggingface mlx-community/gemma-4-E2B-it-qat-4bit --output models/gemma.flm
내부 동작 원리
flama get을 실행하면 다음과 같은 일이 일어납니다:
- Flama가 HuggingFace Hub를 대상으로 모델 식별자 (identifier)를 확인하고, 모델을 구성하는 파일들 (가중치 (weights), 토크나이저 (tokenizer), 설정 (configuration))을 찾아냅니다.
- 파일들은 병렬로 다운로드됩니다 (기본적으로 최대 8개의 병렬 다운로드,
--max-concurrent로 설정 가능). - 모든 파일이 디스크에 저장되면, Flama는 모델 패밀리 (model family), 기원 라이브러리 (originating library), 그리고 모델 이름 및 생성 타임스탬프와 같은 메타데이터 (metadata)를 기록하는 매니페스트 (manifest)와 함께 이들을 단일
.flm아카이브로 패키징합니다.
그 결과, 독립적이고 이식 가능한 아티팩트가 생성됩니다. .flm 형식은 프레임워크에 구애받지 않습니다 (framework-agnostic). 동일한 파일이 vLLM (CUDA가 있는 Linux) 또는 MLX (Apple Silicon)에서 실행될 수 있으며, Flama는 로드 시점에 환경에서 사용 가능한 것에 따라 적절한 백엔드 (backend)를 선택합니다.
모델과 로컬에서 상호작용하기
패키징된 .flm 아티팩트 (artifact)를 생성하고 나면, flama model 명령어를 사용하여 터미널에서 직접 모델과 상호작용할 수 있습니다. 서버도, HTTP도, 코드도 필요 없습니다. 이는 빠른 테스트, 프롬프트 실험 (prompt experimentation), 그리고 파이프라인 스크립팅 (pipeline scripting)에 매우 유용합니다.
flama model run을 이용한 원샷 쿼리 (One-shot queries)
run 서브 명령어 (sub-command)는 모델에 프롬프트 (prompt)를 보내고, 전체 응답이 완료될 때까지 기다린 후 이를 출력합니다:
echo "What is Flama?" | flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm run --system "Be concise."
Flama is a Python framework for building production-ready APIs with a focus on machine learning and generative AI, enabling one-line model serving behind HTTP endpoints.
--param 플래그 (flag)를 사용하여 생성 (generation) 설정을 조정할 수 있습니다:
echo "Explain dependency injection in three sentences." | \
flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm run \
--system "You are a software engineering instructor." \
...
멀티턴 대화 (multi-turn conversations)의 경우, --transport conversation 플래그를 사용하고 JSON 메시지 리스트를 전달하세요:
echo '[{"role": "user", "content": "Hi!"}, {"role": "assistant", "content": "Hello! How can I help?"}, {"role": "user", "content": "What is an API?"}]' | \
flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm run --transport conversation
flama model stream을 이용한 스트리밍 응답 (Streaming responses)
대화형의 토큰 단위 (token-by-token) 경험을 원한다면 (특히 긴 응답을 처리할 때 유용합니다), run 대신 stream을 사용하세요. 토큰이 생성되는 즉시 출력되어 즉각적인 피드백을 받을 수 있습니다:
echo "What is flama (python package)?" | \
flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm stream --system "Be concise."
...
스트리밍 출력은 터미널에 글자 단위로 점진적으로 나타나며, 실제 대화를 하는 듯한 느낌을 줍니다. 이는 더 길고 상세한 응답을 생성하는 모델을 사용할 때 특히 만족스럽습니다.
또한 모델에게 모델 자신과 모델이 실행되는 프레임워크에 대해 물어볼 수도 있습니다:
echo "How do I serve an ML model with Flama?" | \
flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm stream \
--system "You are a helpful assistant that knows about the Flama Python framework."
여러 출력 채널(예: 추론과 출력)을 보고 싶다면, --channel를 전달하세요:
echo "Solve step by step: what is 23 * 47?" | \
flama model mlx-community_gemma-4-E2B-it-qat-4bit.flm stream \
--channel thinking --channel output
HTTP를 통해 모델 서빙하기
Flama의 진정한 강점은 로컬 모델을 단일 명령어로 프로덕션 레디(production-ready) HTTP API로 전환할 수 있다는 점입니다. 파이썬 코드도, 설정 파일도, Docker 이미지도 필요 없습니다. 그저 flama serve만 있으면 됩니다.
flama serve 명령어
앞서 다운로드한 모델을 서빙하려면 다음과 같이 합니다:
flama serve --model file=mlx-community_gemma-4-E2B-it-qat-4bit.flm,url=/,name=gemma
INFO: Started server process [52341]
...
이것으로 끝입니다. 단 하나의 명령어로 모델이 완전한 HTTP API 뒤에서 작동하게 됩니다. --model이 무엇을 허용하는지 자세히 살펴보겠습니다:
file(필수):.flm아티팩트의 경로.url: 모델 엔드포인트가 마운트되는 URL 접두사 (기본값:/).name: 리소스 이름으로, OpenAPI 태그 및 의존성 주입(dependency injection)에 사용됩니다.serving: 활성화할 방언(dialect)의 쉼표로 구분된 목록 (예:native,openai,anthropic,ollama). 생략하면 모든 방언이 마운트됩니다.params: 기본 생성 매개변수 (예:temperature=0.7).
하나의 애플리케이션에서 여러 모델을 서빙할 수 있습니다:
flama serve \
--model file=gemma.flm,url=/gemma,name=gemma,serving=native+openai \
--model file=qwen.flm,url=/qwen,name=qwen,serving=native+anthropic
그리고 일반적인 옵션으로 서버를 구성할 수도 있습니다:
flama serve \
--model file=mlx-community_gemma-4-E2B-it-qat-4bit.flm,url=/,name=gemma \
--server-host 0.0.0.0 \
...
내장 채팅 인터페이스
네이티브 서빙 방언 (native serving dialect)이 활성화되어 있으면 (기본적으로 활성화되어 있음), 모델은 /chat/ 경로(모델의 URL 접두사 기준 상대 경로)를 통해 접근 가능한 내장 채팅 인터페이스를 함께 제공합니다. 만약 모델을 /에서 서빙했다면, http://127.0.0.1:8000/chat/로 이동하세요.
세련되고 프로덕션 품질(production-quality)을 갖춘 채팅 인터페이스가 나타나며, 여기서 프롬프트를 입력하고 모델의 응답이 토큰 단위로 스트리밍되는 것을 확인할 수 있습니다. 이 인터페이스는 Markdown, LaTeX 수학식 (KaTeX를 통해), 그리고 Mermaid 다이어그램을 즉시 렌더링하므로, 기술적인 답변이 의도한 대로 정확하게 표시됩니다.
채팅 인터페이스는 프론트엔드 코드, 빌드 단계, 또는 외부 의존성이 전혀 필요하지 않습니다. 이는 프레임워크에서 직접 서빙되는 독립적인 단일 페이지 애플리케이션 (SPA)입니다. 서빙하는 모든 모델은 각각의 채팅 창(예: /gemma/chat/, /qwen/chat/)을 가지며, 각 창은 해당 모델의 스트리밍 엔드포인트(streaming endpoint)에 연결됩니다.
에이전트 워크플로우 (agentic workflows) 구동
로컬에서 서빙되는 LLM의 가장 매력적인 활용 사례 중 하나는 에이전트 워크플로우 (agentic workflows)를 구동하는 것입니다. Flama는 업계 표준 프로토콜 (OpenAI, Anthropic, Ollama)을 통해 모델을 노출하므로, 해당 프로토콜을 지원하는 모든 도구는 여러분의 로컬 모델을 백엔드로 사용할 수 있습니다.
로컬 모델과 Claude CLI 사용하기
실질적인 예로, Flama로 서빙되는 로컬 모델과 함께 Claude CLI를 사용하는 것이 있습니다. 프롬프트를 Anthropic의 서버로 보내는 대신, 로컬에서 실행 중인 모델을 통해 라우팅할 수 있습니다.
먼저, 모델이 Anthropic 방언 (Anthropic dialect)이 활성화된 상태로 서빙되고 있는지 확인하세요:
flama serve --model file=mlx-community_gemma-4-E2B-it-qat-4bit.flm,url=/,name=gemma,serving=native+anthropic
그 다음, ~/.claude/settings.json (또는 프로젝트별 오버라이드를 위한 .claude/settings.local.json)에 다음 내용을 추가하여 Claude CLI가 로컬 Flama 엔드포인트를 사용하도록 설정하세요:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:8000/anthropic",
...
이러한 설정이 완료되면, 평소와 같이 Claude CLI를 실행하기만 하면 됩니다:
claude
이제 Claude CLI는 Anthropic의 클라우드 대신 로컬에서 Flama로 서빙되는 모델을 통해 모든 요청을 라우팅(route)합니다. 일반적인 상호작용은 다음과 같습니다:
❯ claude
What is this repo about?
...
여러분의 에이전트 작업(agentic tasks, 코드 생성, 파일 편집, 리서치 등)은 전적으로 로컬 하드웨어에서 실행됩니다. 이를 통해 다음과 같은 이점을 얻을 수 있습니다:
- 개인정보 보호 (Privacy): 프롬프트와 코드가 기기를 절대 벗어나지 않습니다.
- 비용 (Cost): 개발 및 실험을 위한 API 사용료가 발생하지 않습니다.
- 속도 (Speed): 클라우드 제공업체로의 네트워크 지연 시간(latency)이 없습니다 (특히 반복적인 에이전트 루프(agent loops)에서 매우 가치 있습니다).
- 제어 (Control): 모델, 양자화 (quantisation), 생성 파라미터를 직접 선택할 수 있습니다.
이와 동일한 패턴은 사용자 정의 API 기본 URL (custom API base URLs)을 지원하는 모든 에이전트 프레임워크(LangChain, CrewAI, AutoGen 또는 기본 URL 설정을 허용하는 모든 커스텀 도구)에서 작동합니다.
결론 (Conclusions)
Flama 2.0은 "LLM을 사용하고 싶다"에서 "프로덕션 준비가 된 API를 보유했다"로 가는 여정을 최대한 단축해 줍니다. CLI는 세 가지 수준의 상호작용을 제공합니다:
flama get: HuggingFace에서 어떤 모델이든 다운로드하여 휴대 가능한.flm아티팩트(artifact)로 패키징합니다.flama model: 빠른 테스트 및 스크립팅을 위해 터미널에서 모델과 직접 상호작용합니다.flama serve: OpenAI/Anthropic/Ollama 호환성, 내장된 채팅 인터페이스 및 스트리밍(streaming) 지원과 함께 HTTP를 통해 모델을 서빙합니다.
보일러플레이트 (boilerplate) Python 코드도, YAML 설정도, 컨테이너 오케스트레이션 (container orchestration)도 필요 없습니다. 오직 CLI만 있으면 됩니다.
Flama가 여러분의 도구들이 이미 이해하고 있는 프로토콜(OpenAI, Anthropic, Ollama)을 사용한다는 사실은, 워크플로우에 로컬 모델을 도입할 때 기본 URL(base URL) 외에는 아무것도 변경할 필요가 없음을 의미합니다. 기존의 SDK, 에이전트 프레임워크, 채팅 인터페이스는 수정 없이 그대로 작동합니다.
다음 포스트에서는 Flama를 사용하여 도구(tools)와 리소스(resources)를 AI 에이전트에게 노출하기 위한 MCP 서버를 구축하는 방법과, 진정으로 강력한 에이전트 애플리케이션 (agentic applications)을 만들기 위해 LLM 서빙을 모델 컨텍스트 프로토콜 (Model Context Protocol)과 결합하는 방법을 살펴볼 예정입니다.
참고 문헌 (References)
- Flama documentation
- Generative AI section
- Flama GitHub repository
- Flama PyPI package
- MLX Community on HuggingFace
저희의 작업을 지원해 주세요
만약 Flama가 견고한 머신러닝 (Machine Learning) 및 생성형 AI (Generative AI) API를 구축하는 데 유용하다고 느끼신다면, GitHub에서 ⭐를 눌러 지원해 주시면 정말 기쁘겠습니다. 여러분의 스타는 저희의 개발 노력을 위한 최고의 연료가 됩니다!
또한 𝕏를 팔로우하여 최신 뉴스 및 개발 스레드에 대한 업데이트를 받아보실 수 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기