簡単
Cloudflare Workers AIでは、サーバーレスGPUを使ってCloudflareのグローバルネットワーク上で機械学習モデルを実行できます。これらのモデルは、Workers、Pages、またはCloudflare APIを使用して独自のコードに統合できます。このプラットフォームは、画像分類、テキスト生成、物体検出など、様々なAIタスクをサポートしています。
主な特徴
モデル さまざまなAIタスクに対応するオープンソースのモデルを幅広く取り揃えています。
請求書。 2024年4月1日以降、非試験モデルの使用は課金対象となる。
リソース Vectorize、R2、D1などの関連製品へのアクセス。
打込む ビッグモデルオフィシャルプラザへ
課金
フリープラン 10,000牛/日(牛はCFのAI通貨単位で使用可能) 公式計算機 計算)、1万頭が利用可能:
- 100~200の対話
- 500の翻訳
- 500秒スピーチ・トゥ・テキスト
- 10,000のテキスト分類
- 1,500~15,000エンベッド
2024年4月1日以降、以下のモデルについては、1日あたり1万頭を超えた場合、1日あたり0.011ドル/kcwで請求される。
- BGE-スモール-エン-V1.5
- ベージベース-エン-v1.5
- BGE-ラージ-エン-V1.5
- ディスティルベール-SST-2-INT8
- ラマ2-7b-チャット-イント8
- ラマ2-7B-チャット-FP16
- ミストラル-7b-インストラクション-v0.1
- m2m100-1.2b
- レスネット-50
- ウィスパー
クレジットの使用量は、CFパネルのAIタブで確認できます:価格|Cloudflare Workers AI ドキュメント
最新のAIフリープランの限度額(2024年11月1日より、新料金体系による全モデルの有料化を開始します)
モデル | フリーレイヤーサイズ |
---|---|
テキスト・ジェネレーション - LLM | 每天 10,000 个 token,适用于任何模型大小 |
埋め込み | 每天 10,000 个 token,适用于任何模型大小 |
写真 | 250 步之和,最高 1024x1024 分辨率 |
音声テキスト | 每天 10 分钟音频 |
簡単スタート
始める前に、まず自分のアカウントを登録し、ログインする必要があります。
アカウントIDの取得
見せる パネルページアドレスバーの最後の/の後の文字列があなたのAccountIDです。
トークン取得
見せる トークン・ページ トークンを作成し、Workers AIを選択する。
OneAPIの設定
対話モデル
キー: 取得するトークン
base_url: https://api.cloudflare.com/client/v4/accounts/AccountID/ai、AccountIDを置き換える。
モデル::
- アット・シー・エフ/deepseek-ai/deepseek-math-7b-インストラクター
- アット・シー・エフ/defog/sqlcoder-7b-2
- アット・シー・エフ/fblgit/una-cybertron-7b-v2-awq
- アット・シー・エフ/fblgit/una-cybertron-7b-v2-bf16
- アット・シー・エフ/google/gemma-2b-it-lora
- アット・シー・エフ/google/gemma-7b-it-lora
- アット・シー・エフ/メタ・ラマ/ラマ2-7b-チャット-hf-ロラ
- アット・シー・エフ/meta/llama-2-7b-chat-fp16
- アット・シー・エフ/meta/llama-2-7b-chat-int8
- アット・シー・エフ/メタ/ラマ3-8bインストラクター
- アット・シー・エフ/meta/llama-3-8b-instruct-awq
- アット・シー・エフ/マイクロソフト/phi-2
- アット・シー・エフ/mistral/mistral-7b-instruct-v0.1
- アット・シー・エフ/mistral/mistral-7b-instruct-v0.1-vllm
- アット・シー・エフ/mistral/mistral-7b-instruct-v0.2-lora(ミストラル-7b-インストラクト-v0.2-ローラ
- アット・シー・エフ/openchat/openchat-3.5-0106
- アット・シー・エフ/qwen/qwen1.5-0.5b-チャット
- アット・シー・エフ/qwen/qwen1.5-1.8b-チャット
- アット・シー・エフ/qwen/qwen1.5-14b-chat-awq
- アット・シー・エフ/qwen/qwen1.5-7b-chat-awq
- アット・シー・エフ/ドイツ語-7b-v1-awq
- アット・シー・エフ/ティウエ/ファルコン-7b-インストラクション
- アット・シー・エフ/tinyllama/tinyllama-1.1b-chat-v1.0
- hf/google/gemma-7b-it
- hf/mistral/mistral-7b-instruct-v0.2
- hf/nexusflow/starling-lm-7b-beta
- hf/nousresearch/hermes-2-pro-mistral-7b
- hf/thebloke/codellama-7b-instruct-awq
- hf/thebloke/deepseek-coder-6.7b-base-awq
- hf/thebloke/deepseek-coder-6.7b-instruct-awq
- hf/thebloke/llama-2-13b-chat-awq
- hf/thebloke/llamaguard-7b-awq
- hf/thebloke/ミストラル-7b-インストラクション-v0.1-awq
- hf/thebloke/ニューラル・チャット-7b-v3-1-awq
- hf/thebloke/openhermes-2.5-mistral-7b-awq
- hf/テブロック/ゼファー-7b-β-awq
POSTの例:
curl --request POST --url https://api.cloudflare.com/client/v4/accounts/${AccountID}//ai/v1/chat/completions \ --header 'Authorization: Bearer token' ¦ヘッダ 'Content-Type: application/json --を入力してください。 --data ' { "model":"@cf/meta/llama-3-8b-instruct"、 「メッセージ": [ { "role": "user", "content": "木のスプーンを3ステップで作るには? "content": "3つの短いステップで木のスプーンを作る方法を教えてください。" "できるだけ短く答えてください。" } ] }
モデルの埋め込み
ダイアログとまったく同じだが、モデルが異なるため、ダイアログと同じチャンネルに置くことができる。
キートークン取得
ベースURL::https://api.cloudflare.com/client/v4/accounts/AccountID/ai
AccountIDの置換
モデル::
- アット・シー・エフ/baai/bge-base-ja-v1.5
- アット・シー・エフ/baai/bge-large-en-v1.5
- アット・シー・エフ/baai/bge-small-en-v1.5
ヴァンセンヌモデル
キートークン取得
ベースURL労働者のアドレスは、デフォルトのアドレスは壁で囲まれているため、ルーティングする必要があります。
モデル::
- アット・シー・エフ/bytedance/stable-diffusion-xl-雷
- アット・シー・エフ/ライコン/ドリームシェイパー-8-Lcm
- アット・シー・エフ/ランウェイml/安定拡散-v1-5-img2img
- アット・シー・エフ/ランウェイml/安定拡散-v1-5-絵画
- アット・シー・エフ/stabilityai/stable-diffusion-xl-base-1.0
worker.jsのコード(AccountIDの置き換えに注意)
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request) { if (request.method === "OPTIONS") { return new Response("", { headers: { 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*' }, status: 204 }); } if (/^(https?:\/\/[^\/]*?)\/file\//i.test(request.url)) { if (request.headers.get("if-modified-since")) { return new Response("", { status: 304, headers: { 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*', "Last-Modified": request.headers.get("If-Modified-Since") }}); } const img = await fetch(request.url.replace(/^(https?:\/\/[^\/]*?)\//, "https://telegra.ph/")); return new Response(img.body, { status: img.status, headers: { "content-type": img.headers.get("content-type"), 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*', "Last-Modified": (new Date()).toUTCString(), "Cache-Control": "public, max-age=31536000" }}); } const url = new URL(request.url); const search = url.searchParams; if (!search.get("debug")) { if (url.pathname !== "/v1/chat/completions" || request.method !== "POST") { return new Response("Not Found or Method Not Allowed", { status: 404, headers: { "Content-Type": "application/json", 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*' } }); } } const authHeader = request.headers.get("Authorization") || "Bearer " + search.get("key"); if (!authHeader || !authHeader.startsWith("Bearer ")) { return new Response("Unauthorized: Missing or invalid Authorization header", { status: 401, headers: { "Content-Type": "application/json", 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*' } }); } const apiKey = authHeader.slice(7); let data; try { data = await request.json(); } catch (error) { if (!search.get("debug")) return new Response("Bad Request: Invalid JSON", { status: 400 }); data = { model: search.get("model") || "@cf/stabilityai/stable-diffusion-xl-base-1.0", messages: [{ role: "user", content: search.get("prompt") || "cat" }] }; } if (!data || !data.model || !data.messages || data.messages.length === 0) { return new Response("Bad Request: Missing required fields", { status: 400 }); } const prompt = data.messages[data.messages.length - 1].content; const cloudflareUrl = `https://api.cloudflare.com/client/v4/AccountID/ai/run/${data.model}`; const requestBody = JSON.stringify({ prompt: prompt, num_inference_steps: 20, guidance_scale: 7.5, strength: 1 }); const currentTimestamp = Math.floor(Date.now() / 1000); const uniqueId = `imggen-${currentTimestamp}`; try { const apiResponse = await fetch(cloudflareUrl, { method: 'POST', headers: { 'Authorization': authHeader, 'Content-Type': 'application/json', }, body: requestBody, }); if (!apiResponse.ok) { throw new Error("Request error: " + apiResponse.status); } const imageBlob = await apiResponse.blob(); const formData = new FormData(); formData.append("file", imageBlob, "image.jpg"); const uploadResponse = await fetch("https://telegra.ph/upload", { method: 'POST', body: formData, }); if (!uploadResponse.ok) { throw new Error("Failed to upload image"); } const uploadResult = await uploadResponse.json(); const imageUrl = request.url.match(/^(https?:\/\/[^\/]*?)\//)[1] + uploadResult[0].src; const responsePayload = { id: uniqueId, object: "chat.completion.chunk", created: currentTimestamp, model: data.model, choices: [ { index: 0, delta: { content: `![](${imageUrl})`, }, finish_reason: "stop", }, ], }; const dataString = JSON.stringify(responsePayload); return new Response(`data: ${dataString}\n\n`, { status: 200, headers: { "Content-Type": "text/event-stream", 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*', }, }); } catch (error) { return new Response("Internal Server Error: " + error.message, { status: 500, headers: { "Content-Type": "application/json", 'Access-Control-Allow-Origin': '*', "Access-Control-Allow-Headers": '*', }, }); } }
音声合成モデル
キートークン取得
ベースURL労働者の住所
モデル::
- アット・シー・エフ/囁き
- アット・シー・エフ/openai/ウィスパー・シェルパ
- アット・シー・エフ/openai/ウィスパー・タイニー-エン
POSTの例:
domain.comがあなたの労働者のアドレスに置き換わっていることに注意してください。
curl -X POST https://domain.com/v1/audio/transcriptions \ -H "Authorisation: Bearer Token" ୧-͈ᴗ-͈)◞ᵒᵒᵒ -F file=@C:╱UsersFolders╱audio.mp3╱ -F model="@cf/openai/whisper -F model="@cf/openai/whisper"
worker.jsのコード(AccountIDの置き換えに注意)
addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)) }) async function handleRequest(request) { const url = new URL(request.url) const { pathname } = url if (request.method === 'POST' && pathname === '/v1/audio/transcriptions') { const formData = await request.formData() const file = formData.get('file') const model = formData.get('model') if (!file || !model) { return new Response('File or model not provided', { status: 400 }) } const apiUrl = `https://api.cloudflare.com/client/v4/accounts/AccountID/ai/run/${model}` const apiResponse = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': request.headers.get('Authorization'), 'Content-Type': 'application/octet-stream' }, body: file.stream() }) const apiResult = await apiResponse.json() const textResult = apiResult.result.text const formattedResult = JSON.stringify({ text: textResult }) return new Response(formattedResult, { headers: { 'Content-Type': 'application/json' } }) } else { return new Response('Not Found', { status: 404 }) } }
翻訳モデル
モデル::
- cf/meta/m2m100-1.2b
サポートされる言語、source_langとtarget_langは同じ範囲です。
- 英語 (ja)
- 中国語(zh)
- フランス語
- ドイツ語 (de)
- スペイン語 (es)
- イタリア語
- 日本語 (ja)
- 韓国語
- ポルトガル語 (pt)
- ロシア語(ru)
- オランダ語
- スウェーデン語 (sv)
- ノルウェー語(いいえ)
- デンマーク語 (da)
- フィンランド語
- ポーランド語
- トルコ語(tr)
- アラビア語
- ヘブライ語
- インドネシア語
- タイ語
- ベトナム語(vi)
- ヒンディー語
- マレー語(ms)
- ギリシャ語
- チェコ語 (cs)
- スロバキア語 (sk)
- ルーマニア語(ro)
- ハンガリー語(hu)
- ブルガリア語 (bg)
- クロアチア語 (hr)
- セルビア語
- ウクライナ語
POSTの例:
curl --request POST --url https://api.cloudflare.com/client/v4/accounts/account_id/ai/run/${model} --header 'Authorization: Bearer token' --header 'Content-Type: application/json' \ --data '{ "source_lang": "en"、 「target_lang": "en"、 "text": "I love you.". }'
イマージョン翻訳
没入型翻訳 開発者設定でベータ版を開き、DeepLX(ベータ版)のアドレス入力を選択します:https://你的worker地址/translate?password=${authKey}。
ワーカー
addEventListener('fetch', event => event.respondWith(handleRequest(event.request))); const model = '@cf/meta/m2m100-1.2b'; const authKey = 'YOUR_PASSWORD'; const accountId = 'YOUR_ACCOUNT_ID'; const トークン = 'YOUR_TOKEN'; async function handleRequest(request) { const url = new URL(request.url); if (request.method === 'OPTIONS') return new Response(null, { status: 204, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' } }); if (request.method !== 'POST' || url.pathname !== '/translate' || url.searchParams.get('password') !== authKey) return new Response(request.method !== 'POST' || url.pathname !== '/translate' ? 'Not Found' : 'Unauthorized', { status: request.method !== 'POST' || url.pathname !== '/translate' ? 404 : 401 }); const data = await request.json(); if (!data.text || !data.source_lang || !data.target_lang) return new Response('Bad Request', { status: 400 }); const cloudflareUrl = `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/run/${model}`; const init = { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ source_lang: data.source_lang.toLowerCase(), target_lang: data.target_lang.toLowerCase(), text: data.text }) }; try { const response = await fetch(cloudflareUrl, init); const responseData = await response.json(); return new Response(JSON.stringify({ alternatives: [], code: 200, data: responseData.result.translated_text, id: Math.floor(Math.random() * 10000000000), source_lang: data.source_lang, target_lang: data.target_lang }), { headers: { 'Content-Type': 'application/json' } }); } catch (error) { console.error('Translation failed:', error); return new Response(JSON.stringify({ error: 'Translation failed' }), { headers: { 'Content-Type': 'application/json' }, status: 500 }); } }