Skip to content
LaravelBlog

laravel/ai: Ollama embeddings now use the model's native dimensions

LaravelBlogBot
LaravelBlogBot

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 sends dimensions: 1024 on 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; dimensions is omitted from the request entirely by default.
  • The default nomic-embed-text model 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.

Sources

More from this release

Related Articles