breve
O Cloudflare Workers AI permite que você execute modelos de aprendizado de máquina na rede global da Cloudflare usando GPUs sem servidor. Você pode integrar esses modelos em seu próprio código por meio de Workers, Pages ou da API da Cloudflare. A plataforma suporta uma variedade de tarefas de IA, incluindo classificação de imagens, geração de texto e detecção de objetos.
Principais recursos.
Modelos. Uma ampla seleção de modelos de código aberto para diferentes tarefas de IA.
Faturamento. A partir de 1º de abril de 2024, o uso de modelos que não sejam de teste será cobrado.
Recursos. Acesso a produtos relacionados, como Vectorize, R2, D1 e outros.
strike (no teclado) Visite o site oficial da Big Model Plaza
faturamento
Plano gratuito 10.000 vacas por dia (as vacas são a unidade monetária de IA da cf e podem ser usadas) Calculadora oficial Calculado), 10.000 vacas disponíveis:
- 100 a 200 diálogos
- 500 traduções
- Discurso para texto de 500 segundos
- 10.000 classificações de texto
- 1.500 a 15.000 incorporações
A partir de 1º de abril de 2024, os modelos a seguir serão cobrados a US$ 0,011/kcw por dia acima de 10.000 vacas por dia
- bge-small-pt-v1.5
- bge-base-pt-v1.5
- bge-large-pt-v1.5
- distilbert-sst-2-int8
- llama-2-7b-chat-int8
- llama-2-7b-chat-fp16
- mistral-7b-instruct-v0.1
- m2m100-1.2b
- resnet-50
- sussurro
O uso do crédito pode ser visualizado na guia AI do painel cf. Consulte as taxas de cobrança específicas:Preços | Cloudflare Workers Documentos de IA
Limitações do plano gratuito do AI para os trabalhadores mais recentes(Começaremos a cobrar por todos os modelos sob a nova estrutura de preços a partir de 1º de novembro de 2024).
Modelo | Tamanho da camada livre |
---|---|
Geração de texto - LLM | 每天 10,000 个 token,适用于任何模型大小 |
incorporação | 每天 10,000 个 token,适用于任何模型大小 |
fotografia | 250 步之和,最高 1024x1024 分辨率 |
conversão de voz em texto | 每天 10 分钟音频 |
Início fácil
Antes de começar, é necessário registrar sua própria conta e fazer o login
Obter ID da conta
show (um ingresso) página do painelA cadeia de caracteres após o último / na barra de endereços é seu AccountID.
Obter token
show (um ingresso) página de token Crie o token, observe a seleção de Workers AI
Configurações da OneAPI
modelo de diálogo
key: o token a ser obtido
base_url: https://api.cloudflare.com/client/v4/accounts/AccountID/ai, substituindo AccountID
modelo::
- @cf/deepseek-ai/deepseek-math-7b-instruct
- @cf/defog/sqlcoder-7b-2
- @cf/fblgit/una-cybertron-7b-v2-awq
- @cf/fblgit/una-cybertron-7b-v2-bf16
- @cf/google/gemma-2b-it-lora
- @cf/google/gemma-7b-it-lora
- @cf/meta-llama/llama-2-7b-chat-hf-lora
- @cf/meta/llama-2-7b-chat-fp16
- @cf/meta/llama-2-7b-chat-int8
- @cf/meta/llama-3-8b-instruct
- @cf/meta/llama-3-8b-instruct-awq
- @cf/microsoft/phi-2
- @cf/mistral/mistral-7b-instruct-v0.1
- @cf/mistral/mistral-7b-instruct-v0.1-vllm
- @cf/mistral/mistral-7b-instruct-v0.2-lora
- @cf/openchat/openchat-3.5-0106
- @cf/qwen/qwen1.5-0.5b-chat
- @cf/qwen/qwen1.5-1.8b-chat
- @cf/qwen/qwen1.5-14b-chat-awq
- @cf/qwen/qwen1.5-7b-chat-awq
- @cf/thebloke/discolm-german-7b-v1-awq
- @cf/tiiuae/falcon-7b-instruct
- @cf/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/mistral-7b-instruct-v0.1-awq
- @hf/thebloke/neural-chat-7b-v3-1-awq
- @hf/thebloke/openhermes-2.5-mistral-7b-awq
- @hf/thebloke/zephyr-7b-beta-awq
Exemplo de POST:
curl --request POST \ --url https://api.cloudflare.com/client/v4/accounts/${AccountID}//ai/v1/chat/completions \ --header 'Authorization: Bearer token' \ --header 'Content-Type: application/json' \ --data ' { "model":"@cf/meta/llama-3-8b-instruct", "messages": [ { "role": "user", "content": "colher de pau em 3 etapas curtas? "content": "como construir uma colher de pau em 3 etapas curtas? dê a resposta mais curta possível" } ] } Dê a resposta mais curta possível" } ] }
Modelos de incorporação
Exatamente igual ao diálogo, exceto que o modelo é diferente e pode ser colocado no mesmo canal que o diálogo
chaveToken obtido
base_url::https://api.cloudflare.com/client/v4/accounts/AccountID/ai
Substituição de AccountID
modelo::
- @cf/baai/bge-base-pt-v1.5
- @cf/baai/bge-large-pt-v1.5
- @cf/baai/bge-small-en-v1.5
Modelo Vincennes
chaveToken obtido
base_urlEndereço padrão: o endereço de seu funcionário, o endereço padrão é isolado e deve ser roteado.
modelo::
- @cf/bytedance/stable-diffusion-xl-lightning
- @cf/lykon/dreamshaper-8-lcm
- @cf/runwayml/stable-diffusion-v1-5-img2img
- @cf/runwayml/stable-diffusion-v1-5-inpainting
- @cf/stabilityai/stable-diffusion-xl-base-1.0
código worker.js(Observe a substituição de 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": '*', }, }); } }
modelo de conversão de texto em fala
chaveToken obtido
base_url: endereço de seu funcionário
modelo::
- @cf/openai/whisper
- @cf/openai/whisper-sherpa
- @cf/openai/whisper-tiny-pt
Exemplo de POST:
Observe a substituição de domain.com pelo endereço de seu funcionário.
curl -X POST https://domain.com/v1/audio/transcriptions \ -H "Autorização: Token do Portador" \ -F file=@C:\Users\Folders\audio.mp3 \ -F model="@cf/openai/whisper"
código worker.js(Observe a substituição de 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 }) } }
modelo de tradução
modelo::
- @cf/meta/m2m100-1.2b
Os idiomas suportados, source_lang e target_lang, estão no mesmo intervalo.
- Inglês (en)
- Chinês (zh)
- Francês (fr)
- Alemão (de)
- Espanhol (es)
- Italiano (it)
- Japonês (ja)
- Coreano (ko)
- Português (pt)
- Russo (ru)
- Holandês (nl)
- Sueco (sv)
- Norueguês (não)
- Dinamarquês (da)
- Finlandês (fi)
- Polonês (pl)
- Turco (tr)
- Árabe (ar)
- Hebraico (ele)
- Indonésio (id)
- Tailandês (th)
- Vietnamita (vi)
- Hindi (hi)
- Malaio (ms)
- Grego (el)
- Tcheco (cs)
- Eslovaco (sk)
- Romeno (ro)
- Húngaro (hu)
- Búlgaro (bg)
- Croata (hr)
- Sérvio (sr)
- Ucraniano (uk)
Exemplo de 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." }'
Tradução por imersão
Tradução imersiva Abra o Beta em Configurações do desenvolvedor e selecione Entrada de endereço do DeepLX (Beta):https://你的worker地址/translate?password=${authKey}
worker.js
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 token = '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 }); } }