본문으로 건너뛰기
버전: docs v25.02

ALO Server Mode (--server) 종합 가이드

이 문서는 ALO 프레임워크의 --server 옵션이 어떻게 동작하는지 소스 코드 수준에서 설명하고, 주요 API 기능과 데이터 처리 방식, 그리고 Titanic 예제를 통해 실제 사용 과정을 안내합니다.


1. --server 모드 개요

alo --server 명령어는 ALO를 단발성 CLI 툴이 아닌, 외부의 HTTP API 요청을 받아 추론(Inference)을 실시간으로 수행하는 API 서버로 실행시키는 기능입니다. 이 모드를 사용하면 ALO의 강력한 MLOps 파이프라인을 외부 시스템이나 어플리케이션과 쉽게 연동할 수 있습니다.


2. 코드 레벨 동작 원리 분석

--server 옵션이 실행되면, 여러 파이썬 파일이 상호작용하여 API 서버를 구동합니다. 주요 흐름은 다음과 같습니다.

단계파일역할
1alo/main.py사용자의 --server 명령어를 인식하고, 프레임워크의 실행 모드를 'server'로 설정합니다.
2alo/alo.py설정된 'server' 모드에 따라 Server 클래스의 인스턴스를 생성합니다.
3alo/api/api_server.pyServer 클래스는 uvicornFastAPI를 사용하여 실제 웹 서버를 구동하고, 외부 요청을 받을 수 있는 API 엔드포인트(e.g., /api/v1/run)를 생성합니다.
4alo/alo.pyAPI 요청이 들어오면, Server 클래스의 handle_api_request 메소드가 요청 데이터를 받아 기존 ALO의 추론 파이프라인(exec_stage)을 실행합니다.
5alo/api/api_server.py파이프라인 실행이 완료되면, 그 결과를 JSON 형태로 API 호출자에게 응답합니다.

상세 코드 흐름

  1. 명령어 파싱 (alo/main.py) 사용자가 alo --server를 입력하면, argparse가 이를 인식하고 settings.computing 값을 'server'로 설정합니다.

    # alo/main.py
    def __run(args):
    # ...
    if args.server:
    settings.computing = 'server' # --server 플래그가 있으면 computing 모드를 'server'로 설정
    # ...
    alo = Alo()
    alo.run()
  2. Server 클래스 선택 (alo/alo.py) Alo() 팩토리 함수는 settings.computing 값에 따라 Server 클래스 인스턴스를 생성하여 반환합니다.

    # alo/alo.py
    alo_mode = {
    # ...
    'server': Server, # 'server' 모드는 Server 클래스를 사용
    }

    def Alo():
    # ...
    compute_mode = settings.computing
    alo_class = alo_mode.get(compute_mode)
    return alo_class()
  3. API 서버 실행 (alo/alo.py, alo/api/api_server.py) Server 객체의 solve() 메소드가 호출되어 FastAPI 기반의 웹 서버를 시작합니다. 이때 API 요청을 처리할 함수로 self.handle_api_request가 지정됩니다.

    # alo/alo.py
    class Server(Computing):
    def solve(self):
    # ... (포트 설정) ...
    run_server(host=api_host, port=api_port, run_function=self.handle_api_request)

    run_server 함수는 uvicorn을 통해 API 서버를 구동하고, /api/v1/run 엔드포인트를 생성합니다.

    # alo/api/api_server.py
    def create_app(run_function):
    app = FastAPI(title="ALO API")

    @app.post("/api/v1/run")
    async def api_run(request: AloRequest):
    args = argparse.Namespace(**request.model_dump())
    run_function(args) # Server.handle_api_request 호출
    return {"status": "success", ...}
    return app

3. 주요 API 기능 및 데이터 처리

ALO 서버는 단순히 추론을 실행하는 것 외에도 데이터 및 모델 업로드를 위한 다양한 API 엔드포인트를 제공합니다.

주요 API 엔드포인트 (alo/api/api_server.py)

  • POST /api/v1/run: ALO의 추론 또는 학습 파이프라인 실행을 요청합니다. 요청 본문에 { "mode": "inference" } 와 같이 실행할 모드를 지정할 수 있습니다.

  • POST /api/v1/data/upload: 이미지, 어노테이션(Bounding Box), 클래스 정보 등을 포함하는 복합적인 데이터를 업로드합니다. 데이터는 JSON 형식으로 직렬화되어 전달됩니다.

  • POST /api/v1/models/upload/tar: 학습된 모델 파일(.tar.gz)과 관련 메타데이터, 설정을 함께 업로드합니다. 모델을 서버에 등록하고 관리하는 데 사용됩니다.

  • GET /api/v1/health: 서버가 정상적으로 동작하는지 확인하는 간단한 상태 체크 엔드포인트입니다. "status": "healthy"를 반환합니다.

Base64 이미지 처리 과정 (alo/api/file_handlers.py)

API를 통해 이미지를 전송할 때, 바이너리 데이터를 안전하게 전달하기 위해 Base64로 인코딩하는 것이 일반적입니다. ALO 서버는 이렇게 전달받은 Base64 문자열을 다시 이미지로 변환하여 처리합니다.

  1. Base64 디코딩: deserialize_data 함수는 API 요청에 포함된 Base64 문자열(data.data)을 base64.b64decode()를 사용해 원본 바이트 데이터로 변환합니다.

  2. 이미지 변환: 디코딩된 바이트 데이터를 메모리 상에서 이미지 파일처럼 다루기 위해 io.BytesIO로 감싼 후, Pillow 라이브러리의 Image.open()을 통해 이미지 객체로 엽니다.

  3. NumPy 배열화: 열린 이미지 객체는 np.array()를 통해 픽셀 데이터를 담은 NumPy 배열로 최종 변환됩니다. 이 배열은 모델의 입력으로 사용되거나 파일로 저장될 수 있습니다.

# alo/api/file_handlers.py - deserialize_data 함수

def deserialize_data(data: SerializedData) -> tuple[Any, str]:
# ...
if data.type == "byte_array":
# 1. Base64 문자열을 디코딩
decoded_data = base64.b64decode(data.data)
# 2. 바이트 데이터를 이미지로 열고 3. NumPy 배열로 변환
result = np.array(Image.open(io.BytesIO(decoded_data)))
return result, "numpy"
# ...

이렇게 변환된 이미지 데이터는 save_image_data 함수를 통해 서버의 파일 시스템에 .jpeg 또는 .npy 파일로 저장되어 추론 파이프라인에서 사용됩니다.

4. ALO API 주요 엔드포인트 입출력 정리

1. ALO 파이프라인 실행

엔드포인트: POST /api/v1/run

설명: ALO의 학습 또는 추론 파이프라인 실행을 원격으로 요청합니다.

입력 (Request Body)

형식: AloRequest 모델 (JSON)

주요 필드:

  • name (string, 선택): 솔루션의 이름입니다.
  • mode (string, 선택): 실행할 모드를 지정합니다. "inference" 또는 "train"을 사용할 수 있으며, 기본값은 "inference" 입니다.
  • computing (string, 선택): 컴퓨팅 환경을 지정합니다. 기본값은 "local" 입니다.
  • log_level (string, 선택): 로그 레벨을 지정합니다. 기본값은 "DEBUG" 입니다.

요청 예시:

{
"mode": "inference"
}

출력 (Response Body)

형식: JSON

주요 필드:

  • status (string): 처리 상태를 나타냅니다. (예: "success")
  • message (string): 처리 결과에 대한 메시지를 포함합니다.
  • inference_result (object, 추론 시): 추론 결과 요약(summary) 등 상세 정보를 포함합니다.
  • context_id (string, 추론 시): 해당 요청을 처리한 고유 실행 ID입니다.

2. 모델 업로드 (.tar)

엔드포인트: POST /api/v1/models/upload/tar

설명: 학습이 완료된 모델을 .tar.gz 압축 파일 형태로 업로드하여 서버에 등록합니다.

입력 (Multipart Form Data)

  • model_file (File): 업로드할 .tar.gz 모델 파일입니다. (필수)
  • metadata (string, 선택): 모델에 대한 추가 정보가 담긴 JSON 형식의 문자열입니다. ModelMetadata 모델을 따릅니다. (name, version, framework, description 등)
  • config (string, 선택): 추가 설정값이 담긴 JSON 형식의 문자열입니다. 기본값은 {} 입니다.

출력 (Response Body)

형식: UploadResponse 모델 (JSON)

주요 필드:

  • status (string): 처리 상태 (예: "success")
  • request_id (string): 이 업로드 요청의 고유 ID
  • model_id (string): 서버에 등록된 모델의 고유 ID
  • result (object): 업로드 결과에 대한 상세 정보 (UploadResult 모델)
    • name (string): 모델 이름
    • version (string): 모델 버전
    • framework (string): 사용된 프레임워크 (예: pytorch, tensorflow)
    • storage_url (string): 모델이 저장된 서버 내 경로
    • metadata (object): 업로드 관련 메타데이터 (UploadMetadata 모델)
    • upload_time (string): 업로드 시간 (ISO 형식)
    • file_size_bytes (integer): 파일 크기

3. 복합 데이터 업로드 (이미지, BBox 등)

엔드포인트: POST /api/v1/data/upload

설명: 이미지, 바운딩 박스(annotation), 클래스 정보 등을 포함하는 복합 데이터를 서버에 업로드합니다. 이미지 데이터는 주로 Base64로 인코딩된 문자열로 전달됩니다.

입력 (Request Body)

형식: DetectionInput 모델 (JSON)

주요 필드:

  • input_data (object): 실제 입력 데이터를 담는 객체 (InputData 모델)
  • image (object, 선택): 직렬화된 이미지 데이터 (SerializedData 모델)
    • type: 데이터 타입 (예: "byte_array")
    • shape: 이미지의 형태 (예: [1080, 1920, 3])
    • dtype: 데이터의 타입 (예: "uint8")
    • data: Base64로 인코딩된 이미지 데이터 문자열
  • annotation_bbox (object, 선택): 직렬화된 바운딩 박스 데이터 (SerializedData 모델)
  • config (object): 실행 설정을 담는 객체 (Config 모델)
  • metadata (object, 선택): 디바이스 ID, 타임스탬프 등 추가 메타데이터 (Metadata 모델)

출력 (Response Body)

형식: JSON

주요 필드:

  • status (string): 처리 상태 (예: "success")
  • request_id (string): 요청의 고유 ID
  • data_id (string): 생성된 데이터의 고유 ID
  • upload_status (string): 업로드 상태 (예: "completed")
  • result (object): 저장된 데이터 정보
    • storage_url (string): 데이터가 저장된 서버 내 경로
    • image_info (object): 이미지의 shape, dtype 등 정보
    • files (object): 서버에 저장된 각 데이터 파일의 상대 경로

4. 서버 상태 확인

엔드포인트: GET /api/v1/health

설명: API 서버가 정상적으로 동작하고 있는지 확인합니다.

입력: 없음

출력 (Response Body)

형식: JSON

내용:

{
"status": "healthy"
}