OllamaとFastAPIを使ってAWS上にDeepSeek R1をセットアップする

2025年2月3日15分で読める

DeepSeek-R1の概要

DeepSeek-R1はMixture of Experts(MoE)アーキテクチャを採用し、パラメータ数は6710億に及びます。MoEアーキテクチャにより370億パラメータを活性化させることができ、クエリを最も関連性の高い「エキスパートクラスター」にルーティングすることで効率的な推論を実現します。このアプローチにより、モデルは全体的な効率を維持しながら、異なる問題領域に特化することができます。DeepSeek-R1は、FP8形式での推論に少なくとも800GBのHBMメモリを必要とします。本記事では、NVIDIA T4 GPUを搭載したg4dnインスタンスを使って、蒸留された70億パラメータモデルをデプロイします。これらのインスタンスは機械学習推論と小規模トレーニングにおいて最もコスト効率が高く、CUDAやCuDNNなどのNVIDIAライブラリで最適化されたグラフィックアプリケーションにおいて高いパフォーマンスを発揮します。

なぜAWS Bedrockを使わないのか?

AWS Bedrockは、LLMをデプロイするための優れたマネージドソリューションを提供していますが、シンガポールと香港のユーザーにとって大きな制約があります——これらのリージョンでは利用できないのです。Bedrockのセットアップの容易さやAWSサービスとの統合という利点があるにもかかわらず、このリージョンの制限により、これらの地域の組織は代替のデプロイオプションを検討せざるを得ません。

クラウドデプロイの利点

大規模言語モデルをローカルで実行するには、特にGPUなどの大量の計算リソースが必要です。DeepSeek R1のようなモデルを効率的に実行できるグラフィックカードを誰もが持っているわけではありません。クラウドデプロイには、次のような複数の利点があります。

  • ハードウェアへの初期投資が不要
  • 需要に応じてスケーラブルなリソース
  • 強力なGPUインスタンス(AWSのg4dnやg5インスタンスなど)へのアクセス
  • 従量課金制によるより良いコスト管理

Ollamaの概要とセキュリティの必要性

OllamaはLLMをローカルで管理・実行するための優れたツールで、以下を提供します。

  • シンプルなモデル管理とデプロイ
  • 使いやすいAPIインターフェース
  • 効率的なモデルの読み込みと提供

出典: https://github.com/ollama/ollama

しかし、Ollamaはクラウドデプロイ向けの組み込みセキュリティ機能を想定して設計されているわけではありません。Ollamaサーバーをインターネットに公開する際は、追加のセキュリティレイヤーが必要です。ここでFastAPIが役立ちます。APIキー認証、レートリミットなどを提供します。

提案するクラウドアーキテクチャ

1. FastAPIサービス

AWS Fargate上にデプロイされ、ポート8080でリクエストを待ち受けます。パブリックサブネットからHTTPSトラフィックを転送するApplication Load Balancer(ALB)を通じて、ユーザーからの受信リクエストを処理します。

2. Ollamaサービス

EC2インスタンス(g4dn.xlarge)上で実行され、ポート11434で待ち受け、FastAPIからのリクエストを処理して特定の計算タスクを実行します。

3. 統合とスケーリング

FastAPIはHTTP経由でOllamaと通信し、Auto Scaling Group(ASG)は需要に応じて1~2台のOllamaインスタンスを維持します。Cloud Mapがサービスディスカバリを促進し、両サービス間の連携を強化します。

4. セキュリティ

このアーキテクチャは、バックエンドサービスをプライベートサブネットに配置し、パブリックトラフィックをALB経由でルーティングすることで、インターネットからの直接アクセスから保護しています。

実装ステップ

1. OllamaとFastAPI用のDockerファイルを準備する

OllamaサービスをセットアップするためのDockerfileを準備します。以下の設定は、公式のOllamaイメージをベースとして使用するイメージを作成します。entrypointスクリプトをイメージ内にコピーし、実行可能にします。次に、DockerfileはバックグラウンドでOllamaサーバーを起動し、準備が完了するまで待機し、DeepSeek R1モデルをプルしてから、コピーしたスクリプトへentrypointを設定し、コンテナ起動時にサーバーが完全に稼働している状態を保証します。

# Use official Ollama image
FROM ollama/ollama:latest

# Copy entrypoint script into the image
COPY entrypoint.sh /entrypoint.sh

# Make script executable
RUN chmod +x /entrypoint.sh

# Start the Ollama server in the background
RUN ollama serve & \
  echo "Waiting for Ollama server to be ready..." && \
  while [ "$(ollama list | grep 'NAME')" = "" ]; do sleep 1; done && \
  echo "Ollama server is ready. Pulling model..." && \
  ollama pull deepseek-r1:7b

# Set entrypoint
ENTRYPOINT ["/entrypoint.sh"]

注:同様に、FastAPIサービス用のDockerfileも、python:3.11-slimのようなベースイメージから始め、依存関係をインストールし、アプリケーションコードをイメージ内にコピーすることで準備できます。

2. FastAPIアプリの準備

このFastAPIアプリケーションは、ユーザーが言語モデルと対話できるAPIを作成します。環境変数から設定を読み込み、検証用のリクエストモデルを定義します。主な機能は /query エンドポイントを通じて提供され、ユーザー入力を受け取り、セキュリティのためにAPIキーを検証し、言語モデルを使用してリクエストを処理します。このアプリケーションはエラーを適切に処理し、問題が発生した場合には適切なHTTPステータスコードとメッセージを返します。

#app.py
from fastapi import FastAPI, HTTPException, Depends, Header, status
from fastapi.responses import JSONResponse
from langchain_ollama import ChatOllama

app = FastAPI()

def create_llm(temperature: float):
    return ChatOllama(
        base_url=OLLAMA_ENDPOINT,
        model=MODEL_NAME,
        temperature=temperature
    )

@app.post('/query')
async def query(data: QueryRequest, authorization: str = Depends(verify_api_key)):
    try:
        llm = create_llm(data.temperature)
        response = llm.invoke(data.message)
        return JSONResponse(content={"response": response.content})
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


if __name__ == '__main__':
    import uvicorn
    uvicorn.run(app, host='0.0.0.0', port=8080)

3. CDKによるインフラ構築

以下を含む、インフラのプロビジョニングにAWS CDKを使用します。

  • GPU対応のEC2インスタンス(g4dn.xlarge)

    // lib/infra-stack.js
    ollamaTaskDef.addContainer('OllamaContainer', {
      image: ecs.ContainerImage.fromAsset(path.join(__dirname, '../../ollama-service')),
      memoryReservationMiB: 4096,
      portMappings: [{ containerPort: 11434 }],
    });
    
    // Create Capacity Provider for GPU instances (g4dn.xlarge)
    const autoScalingGroup = new autoscaling.AutoScalingGroup(this, 'OllamaASG', {
      vpc,
      instanceType: ec2.InstanceType.of(ec2.InstanceClass.G4DN, ec2.InstanceSize.XLARGE),
      machineImage: ecs.EcsOptimizedImage.amazonLinux2(),
      minCapacity: 1,
      maxCapacity: 2,
    });
    
  • HTTPS終端用のApplication Load Balancer

    // Create Application Load Balancer
    const zone = route53.HostedZone.fromLookup(this, 'HostedZone', { domainName });
    const certificate = new acm.Certificate(this, 'Certificate', {
      domainName: <your-domain-name>,
      validation: acm.CertificateValidation.fromDns(zone),
    });
    
    const lb = new elbv2.ApplicationLoadBalancer(this, 'LB', {
      vpc,
      internetFacing: true,
      securityGroup: fastapiSG
    });
    
    const listener = lb.addListener('HttpsListener', {
      port: 443,
      certificates: [certificate],
    });
    
    listener.addTargets('FastapiTarget', {
      port: 8080,
      targets: [fastapiService],
      healthCheck: { path: '/health', interval: cdk.Duration.seconds(30) }
    });
    
    new route53.ARecord(this, 'ARecord', {
      zone,
      recordName: <your-record-name>,
      target: route53.RecordTarget.fromAlias(new targets.LoadBalancerTarget(lb)),
    });
    
  • CDKでAWSインフラをデプロイする

    $cdk deploy --context env="your-environment"

結論

Ollamaのモデル管理機能とFastAPIのセキュリティ機能、AWSのインフラを組み合わせることで、AWS Bedrockが利用できないリージョンにおける本番利用に適した、堅牢で安全かつスケーラブルなDeepSeek R1デプロイを構築できます。

次のステップ:

 support@alphamatch.ai までご連絡いただければ、フルコードへのアクセスと、独自の安全なDeepSeek R1サーバーをセットアップするための詳細な実装ガイド(ステップバイステップの手順)をお送りします。

最新情報をお届け

ニュースとアップデートをいち早くキャッチ