laravel/ai: Ollama embeddings now use the model's native dimensions
Contributed by medilies
Part of the ai v1.2.1 release
Laravel AI's Ollama provider no longer forces a 768-dimensional size onto every embeddings request. Pull request #1115 changes OllamaProvider::defaultEmbeddingsDimensions() to fall back to 0 — meaning "let the model decide" — and opts the provider into native embedding dimensions, mirroring the approach the OpenAI-compatible provider adopted in #841. If you use Ollama embedding models other than the default nomic-embed-text, this changes the size of the vectors you get back, so it deserves a close look before you upgrade from v1.2.0.
The problem: a hardcoded 768 fallback
Previously, whenever models.embeddings.dimensions was not configured, defaultEmbeddingsDimensions() returned 768. That value flowed through PendingEmbeddingsGeneration::generate() into the gateway and onto the wire as dimensions: 768 against Ollama's /api/embed endpoint — and Ollama honors that parameter by truncating vectors to fit.
Only nomic-embed-text (the default) and embeddinggemma are natively 768-dimensional. Larger models were silently truncated: a qwen3-embedding:0.6b request came back with 768 dimensions instead of its native 1024, quietly degrading similarity quality. Smaller models failed outright with errors like dimensions 768 exceeds embedding length 384 from all-minilm or granite-embedding:30m. Even the escape hatch of passing ->dimensions(0) didn't work, because generate() combines values with ?:, which treats 0 as "not set" and re-applies the 768 default.
You could see the discrepancy directly:
curl http://localhost:11434/api/embed \
-d '{"model": "qwen3-embedding:0.6b", "input": ["hello"]}'
# => vectors with 1024 dimensions
Embeddings::for(['hello'])->generate(provider: 'ollama', model: 'qwen3-embedding:0.6b');
// => vectors with 768 dimensions (truncated)
The fix: let the model decide
The provider now defaults to 0 and declares support for native dimensions:
public function defaultEmbeddingsDimensions(): int
{
return $this->config['models']['embeddings']['dimensions'] ?? 0;
}
protected function supportsNativeEmbeddingDimensions(): bool
{
return true;
}
No gateway change was needed: OllamaGateway already omits the dimensions field when it is 0, and FakeEmbeddingGateway already handles that case. With this PR, a request without configured dimensions simply leaves dimensions out of the JSON payload, and Ollama returns whatever vector size the loaded model natively produces — 1024 for qwen3-embedding:0.6b, 384 for all-minilm, and so on.
What still works exactly as before
Two escape hatches are untouched, and they are your tools for controlling behavior after upgrading:
- Configuration still pins the size. Setting
'models' => ['embeddings' => ['dimensions' => 1024]]on the Ollama provider sendsdimensions: 1024on every request, exactly as before. - Explicit per-call dimensions are still sent.
->dimensions(512)reaches Ollama verbatim:
Embeddings::for(['hello'])
->dimensions(512)
->generate(provider: 'ollama', model: 'nomic-embed-text');
Additionally, Ai::instance('ollama')->embeddings(['hello'], model: 'qwen3-embedding:0.6b') previously either threw or forced 768 for a custom model; it now omits dimensions and succeeds.
Upgrade impact: three things to check
1. The default model is unaffected. nomic-embed-text is natively 768-dimensional, so if you never configured dimensions and never changed the model, your vectors are byte-for-byte the same size as before.
2. Other models now return their native size. Vectors generated for models like qwen3-embedding or bge-m3 will no longer match vectors you already stored at 768. If you have an existing vector store, either pin the old behavior in config/ai.php:
'providers' => [
'ollama' => [
// ...
'models' => [
'embeddings' => ['dimensions' => 768],
],
],
],
…or re-index your stored embeddings at the new native size. Pick one and be consistent — mixing 768 and 1024-dimensional vectors in the same index won't work.
3. Automatic fakes now require known dimensions. Embeddings::fake() with Ollama and no configured dimensions now throws Unable to generate fake embeddings without positive dimensions, matching the OpenAI-compatible provider's behavior. Configure models.embeddings.dimensions or provide a fake response in tests.
One smaller note: the embedding cache key includes the dimensions, so entries cached under the old 768 size will miss once and be regenerated at the native size. Expect a one-time re-embedding cost per cached entry, nothing persistent.
Takeaways
- Ollama embeddings now use the model's native dimensions unless you configure or pass an explicit size;
dimensionsis omitted from the request entirely by default. - The default
nomic-embed-textmodel behaves identically to v1.2.0. - If you stored 768-dimensional vectors from other Ollama models, pin
'models' => ['embeddings' => ['dimensions' => 768]]or re-index. Embeddings::fake()without configured dimensions now throws for Ollama; set dimensions or supply a fake response in tests.- Cached Ollama embeddings will miss and regenerate once after upgrading.