🤖 AI/ML

Modal

AI/ML 워크로드를 위한 서버리스 플랫폼

📖 상세 설명

Modal은 AI/ML 워크로드를 위한 서버리스 클라우드 플랫폼으로, Python 코드를 데코레이터 한 줄로 클라우드에서 실행할 수 있게 해줍니다. 2020년에 설립되어 개발자가 인프라 관리 없이 GPU 기반 컴퓨팅 작업에 집중할 수 있도록 설계되었습니다.

Modal의 핵심 철학은 "infrastructure as code"로, 컨테이너 빌드, GPU 할당, 스케일링을 모두 Python 코드 내에서 선언적으로 정의합니다. 콜드 스타트 최적화로 컨테이너가 수 초 내에 시작되며, 사용한 만큼만 비용을 지불하는 과금 체계를 제공합니다.

Modal은 GPU/CPU 클러스터 관리, 컨테이너 빌드 자동화, 분산 처리, 스케줄링, 웹 엔드포인트 배포를 통합 제공합니다. 특히 LLM 추론, 이미지 생성, 배치 처리, 파인튜닝 등 ML 워크로드에 최적화되어 있습니다.

실무에서 Modal은 프로토타입에서 프로덕션까지 동일한 코드로 전환할 수 있어, 스타트업부터 대기업까지 빠른 ML 제품 개발에 활용됩니다. AWS, GCP 대비 설정 복잡성이 크게 감소하며, Hugging Face, vLLM 등과 쉽게 통합됩니다.

기능 Modal AWS Lambda GCP Cloud Run
GPU 지원 A100, H100, A10G 제한적 L4, A100
콜드 스타트 ~1-3초 ~1초 ~5-10초
최대 실행 시간 24시간 15분 60분
과금 단위 초당 ms당 초당
GPU 시간당 비용 A100: $2.78 해당없음 A100: $3.67

💻 코드 예제

Modal을 사용한 GPU 기반 ML 추론 서버 구축 예제입니다.

# pip install modal
import modal

# 앱 정의
app = modal.App("llm-inference")

# GPU 이미지 정의 (vLLM + 모델 캐시)
image = modal.Image.debian_slim().pip_install(
    "vllm", "torch", "transformers"
).run_commands(
    "pip install flash-attn --no-build-isolation"
)

# 모델을 영구 볼륨에 캐시
volume = modal.Volume.from_name("model-cache", create_if_missing=True)

@app.cls(
    gpu="A100",  # GPU 타입 지정
    image=image,
    volumes={"/models": volume},
    timeout=600,
    container_idle_timeout=300,  # 5분간 유휴시 종료
)
class LLMInference:
    @modal.enter()
    def load_model(self):
        """컨테이너 시작시 모델 로드"""
        from vllm import LLM
        self.llm = LLM(
            model="mistralai/Mistral-7B-Instruct-v0.2",
            download_dir="/models",
            max_model_len=4096,
        )

    @modal.method()
    def generate(self, prompt: str, max_tokens: int = 512):
        """텍스트 생성"""
        from vllm import SamplingParams
        params = SamplingParams(
            max_tokens=max_tokens,
            temperature=0.7,
        )
        outputs = self.llm.generate([prompt], params)
        return outputs[0].outputs[0].text

    @modal.web_endpoint(method="POST")
    def api(self, request: dict):
        """웹 API 엔드포인트"""
        prompt = request.get("prompt", "")
        result = self.generate(prompt)
        return {"response": result}


# 배치 처리 함수
@app.function(gpu="A10G", image=image, timeout=3600)
def batch_inference(prompts: list[str]):
    """대량 프롬프트 배치 처리"""
    from vllm import LLM, SamplingParams

    llm = LLM(model="mistralai/Mistral-7B-Instruct-v0.2")
    params = SamplingParams(max_tokens=256)

    outputs = llm.generate(prompts, params)
    return [o.outputs[0].text for o in outputs]


# 스케줄 작업 (매일 자정)
@app.function(schedule=modal.Cron("0 0 * * *"))
def daily_task():
    """일일 배치 작업"""
    print("Daily batch job running...")


# 로컬에서 실행
if __name__ == "__main__":
    with app.run():
        inference = LLMInference()
        result = inference.generate.remote("Explain quantum computing:")
        print(result)

터미널에서 배포 및 실행:

# Modal CLI 설정
modal setup

# 로컬 테스트 실행
modal run app.py

# 프로덕션 배포
modal deploy app.py

# 배치 처리 맵 (병렬 실행)
modal run app.py::batch_inference --input prompts.json

# 서버 로그 확인
modal app logs llm-inference

🗣️ 실무 대화 예시

💼 회의에서

"GPU 서버 관리가 부담되는데, Modal 쓰면 인프라 걱정 없이 A100에서 LLM 돌릴 수 있어요. 배포도 modal deploy 한 줄이면 끝이고, 사용한 시간만 과금되니까 비용도 예측 가능합니다."

🎤 면접에서

"Modal은 서버리스 ML 플랫폼으로, Python 데코레이터로 GPU 컨테이너를 정의합니다. 콜드 스타트가 빠르고, 볼륨으로 모델 캐싱하면 재시작 시에도 빠른 응답이 가능합니다. AWS Lambda의 GPU 버전이라고 보시면 됩니다."

🔧 기술 토론에서

"Modal의 장점은 container_idle_timeout으로 웜 컨테이너 유지하면서 비용 최적화할 수 있다는 거예요. 그리고 .map()으로 수천 개 작업을 병렬 처리하면 EC2 Spot 대비 관리 부담 없이 비슷한 비용으로 배치 처리 가능합니다."

⚠️ 주의사항

잘못된 접근: Modal에서 GPU 타입 지정 없이 기본 실행하면 CPU만 사용됩니다.

올바른 접근: @app.function(gpu="A100") 또는 gpu="A10G" 등 명시적으로 GPU 타입을 지정하세요.

잘못된 접근: 매 요청마다 대형 모델을 다운로드하면 콜드 스타트가 수 분 걸립니다.

올바른 접근: Volume에 모델을 캐싱하고 @modal.enter()에서 한 번만 로드하세요. 이미지 빌드 시 모델을 bake-in 하는 것도 방법입니다.

잘못된 접근: 웹 엔드포인트 timeout을 너무 짧게 설정하면 LLM 생성 중 중단됩니다.

올바른 접근: LLM 추론은 timeout=300 이상 설정하고, 스트리밍이 필요하면 @modal.web_endpoint()에서 generator 반환하세요.

🔗 관련 용어

📚 더 배우기