Skip to content

Document Embeddings Fresh 🌱

Embed PDF documents directly for document search, classification, and retrieval workflows.

Overview

Specifications

ParameterValue
Modelgemini-embedding-2-preview
Max pages6 per request
Supported formatPDF
Default dimensions3,072
Dimension range128 - 3,072
ProcessingNative PDF parsing (text + layout + images)

Step 1: Embed a PDF Document (Python)

python
from google import genai
from google.genai import types

with open('report.pdf', 'rb') as f:
    pdf_bytes = f.read()

client = genai.Client()

result = client.models.embed_content(
    model='gemini-embedding-2-preview',
    contents=[
        types.Part.from_bytes(
            data=pdf_bytes,
            mime_type='application/pdf',
        ),
    ]
)

embedding = result.embeddings[0].values
print(f"Dimensions: {len(embedding)}")  # 3072

Step 2: Embed via cURL

bash
PDF_BASE64=$(base64 -w 0 report.pdf)

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent" \
    -H "Content-Type: application/json" \
    -H "x-goog-api-key: ${GEMINI_API_KEY}" \
    -d '{
        "content": {
            "parts": [{
                "inline_data": {
                    "mime_type": "application/pdf",
                    "data": "'"${PDF_BASE64}"'"
                }
            }]
        }
    }'

Step 3: Handle Long Documents (Splitting)

For PDFs longer than 6 pages, split and embed each section.

python
import PyPDF2
import io
from google import genai
from google.genai import types

def split_and_embed_pdf(pdf_path, pages_per_chunk=6):
    """Split a long PDF into chunks and embed each."""
    client = genai.Client()
    reader = PyPDF2.PdfReader(pdf_path)
    total_pages = len(reader.pages)
    embeddings = []

    for start in range(0, total_pages, pages_per_chunk):
        end = min(start + pages_per_chunk, total_pages)
        writer = PyPDF2.PdfWriter()

        for page_num in range(start, end):
            writer.add_page(reader.pages[page_num])

        buffer = io.BytesIO()
        writer.write(buffer)
        chunk_bytes = buffer.getvalue()

        result = client.models.embed_content(
            model='gemini-embedding-2-preview',
            contents=[types.Part.from_bytes(
                data=chunk_bytes, mime_type='application/pdf'
            )]
        )

        embeddings.append({
            'pages': f'{start + 1}-{end}',
            'embedding': result.embeddings[0].values
        })

    return embeddings

# Usage
embeddings = split_and_embed_pdf('long_report.pdf')
for e in embeddings:
    print(f"Pages {e['pages']}: {len(e['embedding'])} dimensions")

Step 4: Document Search with Text Queries

python
from google import genai
from google.genai import types
import numpy as np

client = genai.Client()

# Embed search query
query = client.models.embed_content(
    model='gemini-embedding-2-preview',
    contents='quarterly revenue growth analysis',
    config=types.EmbedContentConfig(task_type='RETRIEVAL_QUERY')
)
query_vec = np.array(query.embeddings[0].values)

# Embed PDF document
with open('q4_report.pdf', 'rb') as f:
    doc = client.models.embed_content(
        model='gemini-embedding-2-preview',
        contents=[types.Part.from_bytes(
            data=f.read(), mime_type='application/pdf'
        )]
    )
doc_vec = np.array(doc.embeddings[0].values)

similarity = np.dot(query_vec, doc_vec) / (
    np.linalg.norm(query_vec) * np.linalg.norm(doc_vec)
)
print(f"Query-to-document similarity: {similarity:.4f}")

Native PDF Understanding

Gemini Embedding 2 processes PDFs natively, understanding both text content and visual layout elements like tables, charts, and figures. This provides richer embeddings than text-extraction-only approaches.

Verification Checklist

  • [ ] Short PDF (1-6 pages) embedded successfully
  • [ ] Output vector has 3072 dimensions
  • [ ] Long PDF splitting and chunking implemented
  • [ ] Text-to-document cross-modal search tested
  • [ ] Document classification with category vectors verified

Troubleshooting

IssueSolution
PDF too many pagesSplit into 6-page chunks using PyPDF2
Scanned PDF (image-only)Model handles it natively; no OCR needed
Encrypted PDFDecrypt first: pikepdf.open(path, password=pw)
Corrupted PDFValidate with PyPDF2.PdfReader; re-export from source
Large file sizeCompress images in PDF; reduce resolution

See Also

Built with VitePress. Not affiliated with Google.