🦒

gemini-2.5-flash が遅い理由はあの設定だった?

に公開

こんにちは。エンジニアの首無しキリンです。

PeopleX で提供している AI プロダクトは、OpenAI をはじめとした様々なプロバイダを吟味し、ユースケースごとにお客様に提供するのに適したモデルを製品に組み込んでいます。

そのため、プロバイダやモデルの切り替えを頻繁に行います。

生成 AI をプロダクトに組み込む開発者は経験があるかと思いますが、それらは柔軟に切り替えができるように、LangChain や LiteLLM、Vercel社の ai sdk を使っているところも多いのではないでしょうか。

これらはモデルごとのオプションやツール呼び出しの方法を意識することなく統一された書き方で簡単なテキスト引数やクラスを渡すことで切り替えができるように効率を高めてくれます。

私が担当しているプロダクトでも Vercel社の ai sdk を活用しています。

ただし、あまりにもモデルの特徴を意識せずに使ってしまうと思わぬ罠にハマってしまいます。
今回はそのハマりどころについて恥ずかしい経験を書いていきます。

速いと言われていた gemini-2.5-flash が遅い

gemini を使うシーンは様々ですが、今回は「速さ」を意識する場所で実装しようとしていたところでした。

他のプロバイダ(OpenAI や Claudeなど)と同じ感覚で Vercel 社の提供する ai-sdk を用いて gemini を呼び出したところ、思った以上に遅いです。

しかも、OpenAI でいう、 gpt-4o-mini より3倍以上も遅いケースがほとんどで、想定した使い方ができません。

原因 - thinkingConfig

契約したばかり故の Tier* の問題や、リージョンなどを検討したのですが、結局は違う理由でした。

一緒に調査いただいた @joe_re さんの神ムーブによって判明したのですが、 gemini には Thinking Capability といういわゆる Thinking mode のような設定があり、これがデフォルトで有効になっているのが原因でした。

下記のように providerOptions明示的に指定することで thinking をオフにできます。

	const result = await generateText({
		model: google("gemini-2.5-flash"),
		prompt: prompt,
		providerOptions: {
			google: {
				thinkingConfig: {
					thinkingBudget: 0,
					includeThinking: false
				}
			}
		}
	})

速度比較

念のため、thinkingありと、thinkingなし、gpt-4o-mini での速度を比較した結果をサマリに記載します。

質問内容は、即答できるようなもの(thinkingをしたとしてもすぐに回答できるもの)から、少し考える必要があるものまでをピックしてみました。

当然のことながら thinking をオフにすると gpt-4o-mini よりも速い速度で生成してくれました。

質問 gemini-2.5-flash(thinking あり) gemini-2.5-flash(thinking なし) gpt-4o-mini
日本の首都は? 847ms 728ms 1,035ms
日本の県庁所在地を名称のみすべてリストアップしてください 7,643ms 1,739ms 5,177ms
国内主要な自動車メーカー名すべてリストアップしてください 6,873ms 3,665ms 2,799ms
fizz-buzz問題を go で実装してください 7,133ms 2,027ms 2,955ms

なお、性能でいうと県庁所在地の名称リストアップに関してはは唯一 thinking ありのみ正解し、他は東北あたりが欠けていることが多かったです(ちゃんと全部みたわけではないです)

一方で、fizz-buzzを書かせる程度であればどのモデル・設定値もほぼ同じでした。

検証用にサクッと書いたプログラム

import { generateText } from "ai";
import { google } from "@ai-sdk/google";
import { openai } from "@ai-sdk/openai";

const questions = [
	"日本の首都は?",
	"日本の県庁所在地を名称のみすべてリストアップしてください",
	"国内主要な自動車メーカー名すべてリストアップしてください",
	"fizz-buzz問題を go で実装してください",
]

const generateWithGoogle = async (thinking: boolean, prompt: string) => {
	const startTime = performance.now();
	const providerOptions = thinking ? {} :{
		google: {
			thinkingConfig: {
				thinkingBudget: 0,
				includeThinking: false
			}
		}
	}
	const result = await generateText({
		model: google("gemini-2.5-flash"),
		prompt: prompt,
		providerOptions: {
			google: {
				thinkingConfig: {
					thinkingBudget: thinking ? 1000 : 0,
					includeThinking: thinking
				}
			}
		}
	})


	const endTime = performance.now();
	const duration = endTime - startTime;
	console.log(`Google: ${duration}ms. ${result.usage.outputTokens} tokens. reasoning: ${result.usage.reasoningTokens || 0} tokens`);
	console.log(result.text)
}

const generateWithOpenai = async (prompt: string) => {
	const startTime = performance.now();
	const result = await generateText({
		model: openai("gpt-4o-mini"),
		prompt: prompt,
	})
	const endTime = performance.now();
	const duration = endTime - startTime;
	console.log(`OpenAI: ${duration}ms. ${result.usage.outputTokens} tokens`);
	console.log(result.text)
}


const ARGS = process.argv[2];
const main = async () => {
	const thinking = ARGS === "--thinking";
	console.log(`Thinking: ${thinking}`);
	console.log("--------------------------------");

	for (const question of questions) {
		const prompt = `
		質問にのみ回答してください。
		Question: ${question}
		Answer:
		`;
		console.log(question);
		await Promise.all([generateWithGoogle(thinking, prompt), generateWithOpenai(prompt)]);
		console.log("--------------------------------");
	}
}

await main();

まとめ

モデルごとの差分を吸収してくれるフレームワークは便利な反面、モデルごとの特徴について知っておかないと、思わぬ罠にハマるという典型的な事例でした!

社内でも同じくハマってる事例があったので、ご自身のプロジェクトでも速度に影響していないか、不要な thinking を使っていないか確認してみてください。

/以上

GitHubで編集を提案
PeopleXテックブログ

Discussion