Cloudflare Trabajadores AI Modelo Libre Guía comestible

breve

Cloudflare Workers AI te permite ejecutar modelos de aprendizaje automático en la red global de Cloudflare utilizando GPU sin servidor. Puede integrar estos modelos en su propio código a través de Workers, Pages o la API de Cloudflare. La plataforma es compatible con diversas tareas de IA, como la clasificación de imágenes, la generación de texto y la detección de objetos.

 

Características principales.

Modelos. Una amplia selección de modelos de código abierto para diferentes tareas de IA.
Facturación. A partir del 1 de abril de 2024, se facturará el uso de modelos que no sean de prueba.
Recursos. Acceso a productos relacionados como Vectorize, R2, D1 y otros.
golpe (en el teclado) Visite la plaza oficial de Big Model

 

facturación

Plan gratuito 10.000 vacas al día (las vacas son la unidad monetaria AI de cf y pueden utilizarse) Calculadora oficial Calculado), 10.000 vacas disponibles:

  • 100-200 diálogos
  • 500 traducciones
  • 500 segundos de voz a texto
  • 10.000 clasificaciones de texto
  • 1.500-15.000 incrustaciones

 

A partir del 1 de abril de 2024, los siguientes modelos se facturarán a 0,011 $/kcw por día a partir de 10.000 vacas al día

  • bge-pequeño-es-v1.5
  • bge-base-es-v1.5
  • bge-large-es-v1.5
  • destilbert-sst-2-int8
  • llama-2-7b-chat-int8
  • llama-2-7b-chat-fp16
  • mistral-7b-instrucción-v0.1
  • m2m100-1.2b
  • resnet-50
  • susurro

El uso del crédito puede verse en la pestaña AI del panel cf, consulte las tarifas de facturación específicas:Precios | Cloudflare Workers AI docs

 

Limitaciones del último plan gratuito de AI para trabajadores(Empezaremos a cobrar por todos los modelos con la nueva estructura de precios a partir del 1 de noviembre de 2024).

ModeloTamaño de capa libre
Generación de textos - LLM每天 10,000 个 token,适用于任何模型大小
incrustación每天 10,000 个 token,适用于任何模型大小
fotografía250 步之和,最高 1024x1024 分辨率
voz a texto每天 10 分钟音频

 

empezar fácilmente

Antes de empezar, debe registrar su propia cuenta e iniciar sesión.

 

Obtener ID de cuenta

espectáculo (una entrada) página del panelLa cadena después de la última / en la barra de direcciones es su AccountID.

 

Obtener ficha

espectáculo (una entrada) página de fichas Crear la ficha, tenga en cuenta la selección de Trabajadores AI

 

Configuración de OneAPI

modelo de diálogo

Cloudflare Workers AI 免费模型食用指南

 

key: el token a obtener
base_url: https://api.cloudflare.com/client/v4/accounts/AccountID/ai, en lugar de 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-instrucción-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-instrucción-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/elbloque/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

 

Ejemplo POST:

curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/${AccountID}//ai/v1/chat/completions \
--header 'Authorization: Bearer 令牌' \
--header 'Content-Type: application/json' \
--data '
{
"model": "@cf/meta/llama-3-8b-instruct",
"messages": [
{
"role": "user",
"content": "how to build a wooden spoon in 3 short steps? give as short as answer as possible"
}
]
}
'

 

Modelos de incrustación

Exactamente igual que el diálogo, excepto que el modelo es diferente y puede colocarse en el mismo canal que el diálogo.

claveFicha obtenida
URL_base::https://api.cloudflare.com/client/v4/accounts/AccountID/aiSustitución de AccountID
modelo::

  • @cf/baai/bge-base-es-v1.5
  • @cf/baai/bge-large-es-v1.5
  • @cf/baai/bge-small-es-v1.5

 

Modelo Vincennes

claveFicha obtenida
URL_base: la dirección de su trabajador, la dirección por defecto está amurallada y debe ser enrutada.
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(Nótese la sustitución 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 texto a voz

claveFicha obtenida
URL_baseDirección de su trabajador
modelo::

  • @cf/openai/whisper
  • @cf/openai/whisper-sherpa
  • @cf/openai/whisper-tiny-es

Ejemplo POST:

Observe la sustitución de domain.com por la dirección de su trabajador.

curl -X POST https://domain.com/v1/audio/transcriptions \
-H "Authorization: Bearer 令牌" \
-F file=@C:\Users\Folders\audio.mp3 \
-F model="@cf/openai/whisper"

 

código worker.js(Nótese la sustitución 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 traducción

modelo::

  • @cf/meta/m2m100-1.2b

Los idiomas soportados, source_lang y target_lang están en el mismo rango.

  • Inglés (en)
  • Chino (zh)
  • Francés (fr)
  • Alemán (de)
  • Español (es)
  • Italiano (it)
  • Japonés (ja)
  • Coreano (ko)
  • Portugués (pt)
  • Ruso (ru)
  • Neerlandés (nl)
  • Sueco (sv)
  • Noruego (no)
  • Danés (da)
  • Finlandés (fi)
  • Polaco (pl)
  • Turco (tr)
  • Árabe (ar)
  • Hebreo (he)
  • Indonesio (id)
  • Tailandés (th)
  • Vietnamita (vi)
  • Hindi (hi)
  • Malayo (ms)
  • Griego (el)
  • Checo (cs)
  • Eslovaco (sk)
  • Rumano (ro)
  • Húngaro (hu)
  • Búlgaro (bg)
  • Croata (hr)
  • Serbio (sr)
  • Ucraniano (uk)

 

Ejemplo POST:

curl --request POST \
--url https://api.cloudflare.com/client/v4/accounts/account_id/ai/run/${model}\
--header 'Authorization: Bearer 令牌' \
--header 'Content-Type: application/json' \
--data '{
"source_lang": "en",
"target_lang": "zh",
"text": "I love you."
}'

 

Traducción por inmersión

Traducción inmersiva Abre Beta en Ajustes de desarrollador y selecciona Entrada de dirección 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 });
}
}

 

© declaración de copyright

Artículos relacionados

Sin comentarios

Debe iniciar sesión para participar en los comentarios.
Acceder ahora
ninguno
Sin comentarios...