Open6
cloudflare ai で遊ぶ
https://workers-tech.connpass.com/event/300546/ で中の人が来てデモをしてくれて興味を持ったので、遊んでみる。
特に理由はないが Deno でAPIを叩く。
主に日本語が使えるか?というところをテストしている
cloudflare にログインした状態で https://ai.cloudflare.com/ に行くとWebUIで一通り叩ける
API から叩く
.env を用意して API_TOKEN と ACCOUNT_ID を書いておく
CF_API_TOKEN=""
CF_ACCOUNT_ID=""
Deno から叩く
Translate
import "https://deno.land/std@0.206.0/dotenv/load.ts";
const CF_API_TOKEN = Deno.env.get('CF_API_TOKEN')!;
const CF_ACCOUNT_ID = Deno.env.get('CF_ACCOUNT_ID')!;
async function runModel(model: string, args: any) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/ai/run/${model}`,
{
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
method: "POST",
body: JSON.stringify(args),
}
).then((res) => res.json());
}
const response = await runModel('@cf/meta/m2m100-1.2b', {
text: "もう食べられないよ",
source_lang: "japanese",
target_lang: "english"
});
console.log(JSON.stringify(response, null, 2));
出力
$ deno run -A translate.ts
{
"result": {
"translated_text": "I can no longer eat."
},
"success": true,
"errors": [],
"messages": []
}
これは英日も日英もうまくいった。
Text Generation
import "https://deno.land/std@0.206.0/dotenv/load.ts";
const CF_API_TOKEN = Deno.env.get('CF_API_TOKEN')!;
const CF_ACCOUNT_ID = Deno.env.get('CF_ACCOUNT_ID')!;
async function runModel(model: string, args: any) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/ai/run/${model}`,
{
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
method: "POST",
body: JSON.stringify(args),
}
).then((res) => res.json());
}
const res = await runModel('@cf/meta/llama-2-7b-chat-int8', {
messages: [
{ role: 'user', content: "Good morning! It's good weather" }
],
});
console.log(JSON.stringify(res, null, 2));
{
"result": {
"response": "Good morning! Yes, it's a beautiful day outside. It's great to see the sun shining and the birds singing their sweet melodies. The weather is just perfect for a day outdoors, don't you think? 🌞🌻"
},
"success": true,
"errors": [],
"messages": []
}
英語は流暢に話す。
Text Generation: 日本語
import "https://deno.land/std@0.206.0/dotenv/load.ts";
const CF_API_TOKEN = Deno.env.get('CF_API_TOKEN')!;
const CF_ACCOUNT_ID = Deno.env.get('CF_ACCOUNT_ID')!;
async function runModel(model: string, args: any) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/ai/run/${model}`,
{
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
method: "POST",
body: JSON.stringify(args),
}
).then((res) => res.json());
}
const res = await runModel('@cf/meta/llama-2-7b-chat-int8', {
messages: [
{ role: 'user', content: "世界で一番高い山の高さは?" }
],
});
console.log(JSON.stringify(res, null, 2));
$ deno run -A run.ts
{
"result": {
"response": "The highest mountain in the world is Mount Everest, located in the Himalayas on the border between Nepal and Tibet, China. It stands at an elevation of 8,848 meters (29,029 feet) above sea level. This is the highest peak on Earth and has been recognized as the highest mountain in the world since 1865, when the height was first accurately measured."
},
"success": true,
"errors": [],
"messages": []
}
いろいろ試した感じ、日本語を理解できるが、日本語を喋る能力を持たない。
Speech Recoginition
import "https://deno.land/std@0.206.0/dotenv/load.ts";
const CF_API_TOKEN = Deno.env.get('CF_API_TOKEN')!;
const CF_ACCOUNT_ID = Deno.env.get('CF_ACCOUNT_ID')!;
async function runModel(model: string, args: any) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/ai/run/${model}`,
{
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`,
'Content-Type': 'application/json',
},
method: "POST",
body: JSON.stringify(args),
}
).then((res) => res.json());
}
const blob = await Deno.readFile('./task-smp.mp3');
const response = await runModel('@cf/openai/whisper', {
audio: [...blob],
});
console.log(JSON.stringify(response, null, 2));
データは https://clrd.ninjal.ac.jp/csj/sample.html からお借りした。
$ wget https://clrd.ninjal.ac.jp/csj/sound-f/task-smp.mp3
$ deno run -A run.ts
$ deno run -A whisper.ts
{
"result": {
"text": "I'll open it. My name is... I have a name. Is that so? I'll read the name and go up. Hira's Lemy. Hira's Lemy, Lurio... Hira's Lemi. Hira's Lemi, Oryori, Oryori, Oryori, KENQIU, KANASU, Yes, I drew a picture of it. Yes. Seruji... Yes. Yes, Lemi is a hard one. Seruji O H5. This is...",
"word_count": 55,
"words": [
{
"word": "I'll",
"start": 0,
"end": 0.699999988079071
},
{
"word": "open",
"start": 0.699999988079071,
"end": 0.699999988079071
},
{
"word": "it.",
"start": 0.699999988079071,
"end": 2.4800000190734863
},
// 略
]
},
"success": true,
"errors": [],
"messages": []
}
これもテキスト生成と一緒で、日本語は理解はできているが英語に翻訳されて返ってくる。
おそらくコーパスがないのでセルジオ越後が Seruji O H5 になってるのがちょっと面白い。
Text to Image
Stable Diffusion が使える。
よくある感じのアニメ風の画像生成プロンプトを入れてみた。
import "https://deno.land/std@0.206.0/dotenv/load.ts";
const CF_API_TOKEN = Deno.env.get('CF_API_TOKEN')!;
const CF_ACCOUNT_ID = Deno.env.get('CF_ACCOUNT_ID')!;
async function runModelAsArrayBuffer(model: string, args: any) {
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${CF_ACCOUNT_ID}/ai/run/${model}`,
{
method: "POST",
headers: {
'Authorization': `Bearer ${CF_API_TOKEN}`
},
body: JSON.stringify(args),
}
).then((res) => res.arrayBuffer());
}
const response = await runModelAsArrayBuffer('@cf/stabilityai/stable-diffusion-xl-base-1.0', {
prompt: "best quality, masterpiece, anime style, 1 girl, from above, full body, walking, in the ruin"
});
await Deno.writeFile('./girl.png', new Uint8Array(response));
日本語に関しては、cyberpunk cat の代わりに宇宙猫とか試してみたけど、普通の猫しか生成されない。あんまり言語理解が高くなさそう?