File size: 7,379 Bytes
962f426
 
 
 
 
 
 
 
 
 
cf7f643
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
---
title: api_light_hf
emoji: 🚀
colorFrom: blue
colorTo: indigo
sdk: docker
app_file: app.py
pinned: false
---

# api_light_hf

`api_light_dev` の全エンドポイントを **Hugging Face Inference API** に乗せ換えた FastAPI サーバーです。  
Gradio / GCP / Vertex AI への依存を排除し、`HF_TOKEN` 一本で動きます。

---

## アーキテクチャ概要

```
api_light_hf/
├── app.py                  # FastAPI エントリーポイント。apis/ を動的ロード
├── apis/                   # 各 API 関数(1ファイル = 1関数)
├── src/
│   ├── clients/
│   │   └── llm_client.py   # HF Inference API 統合クライアント
│   ├── config/
│   │   └── models.yaml     # モデルエイリアス・タスク定義
│   └── utils/
│       └── tracer.py       # ロギング/OpenTelemetry トレーサー
├── requirements.txt
└── Dockerfile
```

### 主な変更点(api_light_dev との差分)

| 項目 | api_light_dev | api_light_hf |
|---|---|---|
| サーバー | Gradio | FastAPI (`POST /{api_name}`) |
| LLM バックエンド | OpenAI / Vertex AI / LiteLLM | HF Inference API (`huggingface_hub`) |
| OCR | Google Vision API | VLM (Qwen2.5-VL) |
| Inpaint | Vertex AI Imagen | HF `stable-diffusion-inpainting` |
| Image Generation | Vertex AI Imagen / DALL-E | HF FLUX.1-dev |
| HTML 生成 (baseimg2html) | Vertex AI Gemini 2.5 Pro | HF Qwen2.5-VL-72B |
| 認証 | GCP サービスアカウント JSON | `HF_TOKEN` 環境変数のみ |

---

## セットアップ

### 1. 環境変数

| 変数 | 必須 | 説明 |
|---|---|---|
| `HF_TOKEN` | ✅ | Hugging Face の API トークン([取得](https://huggingface.co/settings/tokens)) |
| `PORT` | – | 待ち受けポート(デフォルト `7860`) |
| `HF_MODEL` | – | デフォルトモデルの上書き(例: `meta-llama/Llama-3.3-70B-Instruct`) |
| `GCP_SERVICE_KEY_FOR_TRACE` | – | OpenTelemetry / Cloud Trace を有効化する場合のサービスアカウント JSON |

### 2. ローカル起動

```bash
# 依存インストール
pip install -r requirements.txt

# 起動
HF_TOKEN=hf_xxx uvicorn app:app --host 0.0.0.0 --port 7860 --reload
```

### 3. Docker

```bash
# ビルド
docker build -t api_light_hf .

# 実行
docker run -p 7860:7860 -e HF_TOKEN=hf_xxx api_light_hf
```

### 4. Hugging Face Spaces へのデプロイ

専用スクリプト `deploy_api_light_hf.py`(リポジトリルート `DD/` 直下)を使います。

#### 前提

| 条件 | 内容 |
|---|---|
| `HF_TOKEN` | 書き込み権限のある HF API トークン([取得](https://huggingface.co/settings/tokens)) |
| Space の作成 | HF Spaces で **Docker** SDK の Space を先に作成しておく |
| `git` | ローカルに git がインストールされていること |

#### 基本コマンド

```bash
# 環境変数に HF_TOKEN を設定
export HF_TOKEN=hf_xxxxxxxxxxxx

# デプロイ(初回・更新共通)
python deploy_api_light_hf.py --org DLPO --space api_light_hf

# コミットメッセージを指定
python deploy_api_light_hf.py --org DLPO --space api_light_hf -m "feat: add new api"

# push せずに手順を確認する(ドライラン)
python deploy_api_light_hf.py --org DLPO --space api_light_hf --dry-run

# Space の現在の状態を確認
python deploy_api_light_hf.py status --org DLPO --space api_light_hf
```

#### 引数一覧

| 引数 | デフォルト | 説明 |
|---|---|---|
| `cmd` | `deploy` | `deploy` または `status` |
| `--org` | `DLPO` または env `HF_ORG` | HF 組織名 / ユーザー名 |
| `--space` | `api_light_hf` または env `HF_SPACE` | Space 名 |
| `--branch` | `main` | 対象ブランチ |
| `-m / --message` | タイムスタンプ付き自動生成 | コミットメッセージ |
| `--token` | env `HF_TOKEN` | HF API トークン |
| `--local-dir` | `<スクリプトと同階層>/api_light_hf` | ローカルのソースディレクトリ |
| `--dry-run` | false | push せず手順だけ表示 |

#### 失敗時のチェックポイント

- `[error] HF_TOKEN is not set``export HF_TOKEN=hf_xxx` を実行
- `Push failed` → トークンに `write` 権限があるか、Space が存在するか確認
- `Local directory not found``--local-dir` で正しいパスを指定
- `git is not available` → git をインストールして PATH を通す

#### Space の secrets 設定

デプロイ後、Space の **Settings > Repository secrets** に以下を登録してください。

| Secret 名 | 値 |
|---|---|
| `HF_TOKEN` | Inference API 呼び出し用トークン(アプリ内部で使用) |

---

## API の使い方

サーバー起動後、`POST /{api_name}` にリクエストします。

### エンドポイント一覧の確認

```
GET /endpoints
```

### リクエスト形式

```bash
curl -X POST http://localhost:7860/text2theme \
  -H "Content-Type: application/json" \
  -d '{"text": "健康志向の若者向けスポーツドリンク"}'
```

### ヘルスチェック

```
GET /health          → {"status": "ok"}
GET /                → {status, uptime_seconds, active_requests, endpoints}
```

---

## モデル設定

`src/config/models.yaml` でモデルのエイリアス・タスク・能力を管理します。

```yaml
default_model: meta-llama/Llama-3.3-70B-Instruct

aliases:
  gpt-4o: meta-llama/Llama-3.3-70B-Instruct
  gemini-flash: Qwen/Qwen2.5-72B-Instruct
  vision: Qwen/Qwen2.5-VL-72B-Instruct
  ...

models:
  meta-llama/Llama-3.3-70B-Instruct:
    task: text-generation
    supports_json: true
    supports_images: false
  Qwen/Qwen2.5-VL-72B-Instruct:
    task: image-text-to-text
    supports_json: true
    supports_images: true
  ...
```

---

## api_light_dev からの切り替え手順

1. `HF_TOKEN` を発行・設定する
2. `docker build` または `pip install` でセットアップ
3. 旧サービス(Gradio)と並行稼働で動作確認
4. 呼び出し元のベース URL を `https://<gradio-space>/...` から `http://<new-host>:<port>/...` に変更
   - エンドポイント名(`text2theme`, `baseimg2score` など)はそのまま維持
   - リクエストボディは `{"key": "value"}` 形式(旧 Gradio の JSON Body と互換)
5. 旧サービスを停止

### 非互換点

| 項目 | 旧(api_light_dev) | 新(api_light_hf) |
|---|---|---|
| `gcp_key` 引数 | GCP 認証に使用 | 受け取るが無視(ログ警告なし) |
| `openai_key` / `google_api_key` | LLM 認証に使用 | 受け取るが無視 |
| OCR 精度 | Google Vision API | VLM ベース(精度はモデルに依存) |
| Inpaint モデル | Vertex Imagen | SD-Inpainting(品質差あり) |

---

## 新しい API の追加

`apis/` に Python ファイルを追加するだけで自動登録されます。

```python
# apis/my_new_api.py
from src.clients.llm_client import LLMClient
from pydantic import BaseModel

class MyOutput(BaseModel):
    result: str

def my_new_api(input_text: str) -> dict:
    """
    input1 (text): 入力テキスト
    output1 (json): {"result": "..."}
    """
    client = LLMClient()
    output = client.call(prompt=input_text, schema=MyOutput)
    return output.model_dump()
```

サーバーを再起動すると `POST /my_new_api` が自動的に有効になります。