跳转到内容
搜索文档

Cloudflare Workers AI 上的 Whisper-large-v3-turbo

最后更新 查看 MarkdownAgent 设置

在本教程中,你将学习如何:

  • 转录大型音频文件: 使用 Cloudflare Workers AI 的 Whisper-large-v3-turbo 模型执行自动语音识别(ASR)或翻译。
  • 处理大型文件: 将大型音频文件拆分为较小块进行处理,有助于克服内存和执行时间限制。
  • 使用 Cloudflare Workers 部署: 在 serverless 环境中创建可扩展、低延迟的转录管道。

1:创建新的 Cloudflare Worker 项目

  1. 注册 Cloudflare 账户
  2. 安装 Node.js

Node.js 版本管理器

使用 Voltanvm 等 Node 版本管理器,以避免权限问题并切换 Node.js 版本。本指南后续将介绍的 Wrangler 需要 Node 版本 16.17.0 或更高。

你将使用 create-cloudflare CLI(C3)创建新的 Worker 项目。C3 是一个命令行工具,旨在帮助你设置新应用并部署到 Cloudflare。

运行以下命令创建名为 whisper-tutorial 的新项目:

npm create cloudflare@latest -- whisper-tutorial

运行 npm create cloudflare@latest 会提示你安装 create-cloudflare,并引导你完成设置。C3 还会安装 Wrangler,即 Cloudflare Developer Platform CLI。

进行设置时,请选择以下选项:

  • 对于 What would you like to start with?,选择 Hello World example
  • 对于 Which template would you like to use?,选择 Worker only
  • 对于 Which language do you want to use?,选择 TypeScript
  • 对于 Do you want to use git for version control?,选择 Yes
  • 对于 Do you want to deploy your application?,选择 No(部署前我们还会做一些修改)。

这将创建新的 whisper-tutorial 目录。新的 whisper-tutorial 目录将包含:

进入应用目录:

cd whisper-tutorial

2. 将 Worker 连接到 Workers AI

Worker 必须创建 AI 绑定(binding)才能连接到 Workers AI。绑定(binding) 允许 Worker 与 Cloudflare Developer Platform 上的资源(如 Workers AI)交互。

要将 Workers AI 绑定到 Worker,在 Wrangler 配置文件末尾添加以下内容:

{
	"ai": {
		"binding": "AI"
	}
}
[ai]
binding = "AI"

绑定在 Worker 代码中可用,通过 env.AI

3. 配置 Wrangler

在 wrangler 文件中,添加或更新以下设置以启用 Node.js API 和 polyfill(兼容日期为 2024‑09‑23 或更高):

{
	"compatibility_flags": [
		"nodejs_compat"
	],
	// Set this to today's date
	"compatibility_date": "2026-08-17"
}
compatibility_flags = [ "nodejs_compat" ]
# Set this to today's date
compatibility_date = "2026-08-17"

4. 使用分块处理大型音频文件

src/index.ts 文件内容替换为以下集成代码。此示例演示如何:

(1) 从查询参数中提取音频文件 URL。

(2) 获取音频文件并显式跟随重定向。

(3) 将音频文件拆分为较小块(例如 1 MB 块)。

(4) 通过 Cloudflare AI 绑定(binding)使用 Whisper-large-v3-turbo 模型转录每个块。

(5) 以纯文本形式返回聚合的转录结果。

import { Buffer } from "node:buffer";
import type { Ai } from "workers-ai";

export interface Env {
	AI: Ai;
	// If needed, add your KV namespace for storing transcripts.
	// MY_KV_NAMESPACE: KVNamespace;
}

/**
 * Fetches the audio file from the provided URL and splits it into chunks.
 * This function explicitly follows redirects.
 *
 * @param audioUrl - The URL of the audio file.
 * @returns An array of ArrayBuffers, each representing a chunk of the audio.
 */
async function getAudioChunks(audioUrl: string): Promise<ArrayBuffer[]> {
	const response = await fetch(audioUrl, { redirect: "follow" });
	if (!response.ok) {
		throw new Error(`Failed to fetch audio: ${response.status}`);
	}
	const arrayBuffer = await response.arrayBuffer();

	// Example: Split the audio into 1MB chunks.
	const chunkSize = 1024 * 1024; // 1MB
	const chunks: ArrayBuffer[] = [];
	for (let i = 0; i < arrayBuffer.byteLength; i += chunkSize) {
		const chunk = arrayBuffer.slice(i, i + chunkSize);
		chunks.push(chunk);
	}
	return chunks;
}

/**
 * Transcribes a single audio chunk using the Whisper‑large‑v3‑turbo model.
 * The function converts the audio chunk to a Base64-encoded string and
 * sends it to the model via the AI binding.
 *
 * @param chunkBuffer - The audio chunk as an ArrayBuffer.
 * @param env - The Cloudflare Worker environment, including the AI binding.
 * @returns The transcription text from the model.
 */
async function transcribeChunk(
	chunkBuffer: ArrayBuffer,
	env: Env,
): Promise<string> {
	const base64 = Buffer.from(chunkBuffer, "binary").toString("base64");
	const res = await env.AI.run("@cf/openai/whisper-large-v3-turbo", {
		audio: base64,
		// Optional parameters (uncomment and set if needed):
		// task: "transcribe",   // or "translate"
		// language: "en",
		// vad_filter: "false",
		// initial_prompt: "Provide context if needed.",
		// prefix: "Transcription:",
	});
	return res.text; // Assumes the transcription result includes a "text" property.
}

/**
 * The main fetch handler. It extracts the 'url' query parameter, fetches the audio,
 * processes it in chunks, and returns the full transcription.
 */
export default {
	async fetch(
		request: Request,
		env: Env,
		ctx: ExecutionContext,
	): Promise<Response> {
		// Extract the audio URL from the query parameters.
		const { searchParams } = new URL(request.url);
		const audioUrl = searchParams.get("url");

		if (!audioUrl) {
			return new Response("Missing 'url' query parameter", { status: 400 });
		}

		// Get the audio chunks.
		const audioChunks: ArrayBuffer[] = await getAudioChunks(audioUrl);
		let fullTranscript = "";

		// Process each chunk and build the full transcript.
		for (const chunk of audioChunks) {
			try {
				const transcript = await transcribeChunk(chunk, env);
				fullTranscript += transcript + "\n";
			} catch (error) {
				fullTranscript += "[Error transcribing chunk]\n";
			}
		}

		return new Response(fullTranscript, {
			headers: { "Content-Type": "text/plain" },
		});
	},
} satisfies ExportedHandler<Env>;

5. 部署 Worker

  1. 本地运行 Worker:

    使用 wrangler 开发模式在本地测试 Worker:

npx wrangler dev

打开浏览器并访问 http://localhost:8787,或使用 curl:

curl "http://localhost:8787?url=https://raw.githubusercontent.com/your-username/your-repo/main/your-audio-file.mp3"

将 URL 查询参数替换为音频文件的直接链接。(对于 GitHub 托管的文件,请确保使用 raw 文件 URL。)

  1. 部署 Worker:

    测试完成后,使用以下命令部署 Worker:

npx wrangler deploy
  1. 测试已部署的 Worker:

    部署后,通过将音频 URL 作为查询参数传递来测试 Worker:

curl "https://<your-worker-subdomain>.workers.dev?url=https://raw.githubusercontent.com/your-username/your-repo/main/your-audio-file.mp3"

请确保将 <your-worker-subdomain>your-usernameyour-repoyour-audio-file.mp3 替换为你的实际信息。

如果成功,Worker 将返回音频文件的转录:

This is the transcript of the audio...

这篇文档对您有帮助吗?