Spaces:
Running
Running
# app.py | |
import os | |
from fastapi import FastAPI, HTTPException | |
from pydantic import BaseModel | |
from huggingface_hub import hf_hub_download | |
from llama_cpp import Llama # llama-cpp-python をインポート | |
# ----------------------------------------------------------------------------- | |
# Hugging Face Hub の設定 | |
# ----------------------------------------------------------------------------- | |
HF_TOKEN = os.environ.get("HF_TOKEN") # 必要に応じて Secrets にセット | |
REPO_ID = "google/gemma-3-4b-it-qat-q4_0-gguf" | |
# 実際にリポジトリに置かれている GGUF ファイル名を確認してください。 | |
# 例: "gemma-3-4b-it-qat-q4_0-gguf.gguf" | |
GGUF_FILENAME = "gemma-3-4b-it-q4_0.gguf" | |
# キャッシュ先のパス(リポジトリ直下に置く場合) | |
MODEL_PATH = os.path.join(os.getcwd(), GGUF_FILENAME) | |
# ----------------------------------------------------------------------------- | |
# 起動時に一度だけダウンロード | |
# ----------------------------------------------------------------------------- | |
if not os.path.exists(MODEL_PATH): | |
print(f"Downloading {GGUF_FILENAME} from {REPO_ID} …") | |
hf_hub_download( | |
repo_id=REPO_ID, | |
filename=GGUF_FILENAME, | |
token=HF_TOKEN, | |
repo_type="model", # 明示的にモデルリポジトリを指定 | |
local_dir=os.getcwd(), # カレントディレクトリに保存 | |
local_dir_use_symlinks=False | |
) | |
# ----------------------------------------------------------------------------- | |
# llama-cpp-python で 4bit GGUF モデルをロード | |
# ----------------------------------------------------------------------------- | |
print(f"Loading model from {MODEL_PATH}...") | |
try: | |
llm = Llama( | |
model_path=MODEL_PATH, | |
n_ctx=2048, # コンテキストサイズ (モデルに合わせて調整してください) | |
# n_gpu_layers=-1, # GPU を使う場合 (Hugging Face Spaces 無料枠では通常 0) | |
n_gpu_layers=0, # CPU のみ使用 | |
verbose=True # 詳細ログを出力 | |
) | |
print("Model loaded successfully.") | |
except Exception as e: | |
print(f"Error loading model: {e}") | |
# エラーが発生した場合、アプリケーションを終了させるか、エラーハンドリングを行う | |
# ここでは簡単なエラーメッセージを出力して終了する例 | |
raise RuntimeError(f"Failed to load the LLM model: {e}") | |
# ----------------------------------------------------------------------------- | |
# FastAPI 定義 | |
# ----------------------------------------------------------------------------- | |
app = FastAPI(title="Gemma3-4B-IT Q4_0 GGUF API") | |
async def read_root(): | |
return {"message": "Gemma3 API is running"} | |
class GenerationRequest(BaseModel): | |
prompt: str | |
max_new_tokens: int = 128 | |
temperature: float = 0.8 | |
top_p: float = 0.95 | |
# llama-cpp-python で利用可能な他のパラメータも追加可能 | |
# stop: list[str] | None = None | |
# repeat_penalty: float = 1.1 | |
async def generate(req: GenerationRequest): | |
if not req.prompt: | |
raise HTTPException(status_code=400, detail="`prompt` は必須です。") | |
try: | |
# llama-cpp-python の __call__ メソッドで生成 | |
output = llm( | |
req.prompt, | |
max_tokens=req.max_new_tokens, | |
temperature=req.temperature, | |
top_p=req.top_p, | |
# stop=req.stop, # 必要なら追加 | |
# repeat_penalty=req.repeat_penalty, # 必要なら追加 | |
) | |
# 生成されたテキストを取得 | |
generated_text = output["choices"][0]["text"] | |
return {"generated_text": generated_text} | |
except Exception as e: | |
print(f"Error during generation: {e}") | |
raise HTTPException(status_code=500, detail=f"生成中にエラーが発生しました: {e}") | |
# ----------------------------------------------------------------------------- | |
# Uvicorn サーバーの起動 (Hugging Face Spaces 用) | |
# ----------------------------------------------------------------------------- | |
# if __name__ == "__main__": ガードは付けずに直接実行 | |
import uvicorn | |
# Hugging Face Spaces で標準的に使用されるポート 7860 を明示的に指定 | |
port = 7860 | |
# port = int(os.environ.get("PORT", 7860)) # 環境変数があればそれを使う方が良い場合もある | |
# host="0.0.0.0" でコンテナ外からのアクセスを許可 | |
uvicorn.run(app, host="0.0.0.0", port=port, log_level="info") | |