
In my previous blogs we explored how Gemini in BigQuery analyses multimodal data and powers image search with vector embeddings. This blog series moves from the prototype to production, where a new question appears once real volume arrives: what does every Gemini vision call cost, and how do you bring that cost down without losing the answer?
Imagine a marketplace with thousands of new product listings a day. Each listing has a title, a few attributes (product type, colour, pattern, brand) and up to eight photos. Before a listing goes live, we want Gemini to audit it:
- Do the photos actually show the product?
- Does what we see match what the listing says?
A listing that says navy blue leather ankle boot but shows a black boot gets flagged. Photos that are blurry, or are size charts and banners instead of the product, are reported too.
With eight photos per listing, image tokens dominate the bill, so every decision about images is a cost decision. The levers below are what I learned running Gemini vision pipelines at scale.
Which Gemini? I measured on Gemini 3.5 Flash-Lite. The levers apply to the current Gemini 3 models (Pro, Flash, Flash-Lite) and Gemini 4 Argon: both use the same per-image token budgets and media_resolution settings (Token counts table). Other limits, such as Gemini 4’s shared context window, differ but don’t change these levers; where a setting does differ, such as thinking levels, I point it out. Measured numbers come from about 23,000 Gemini calls logged while I ran the pipeline in production on a small subset of the workload.
How the audit works. Two model steps, then plain code:
- Photo check: for every photo, what does it show (product, size chart, banner, packaging), and is it usable (not blurry, product clearly visible)?
- Match check: compare the usable photos with the listing, field by field.
- Decide: turn the answer into an action (PASS, FLAG or REVIEW) in plain Python.
To try this yourself, the public Amazon Berkeley Objects (ABO) dataset has about 147,000 product listings with photos and attributes such as colour, pattern and brand. It is released under CC BY 4.0 (credit: Amazon.com). The companion GitHub repo reproduces every estimate in this post and runs both pipeline designs on a small sample from it.
In this blog we will see:
- A. Where multimodal tokens come from
- B. Lever 1: Choosing the media resolution per step (Code Example 1)
- C. Lever 2: Caching results you don’t need to recompute (Code Example 2)
- D. Lever 3: One call for all photos (Code Example 3)
- E. Lever 4: Trimming the prompt and the thinking level
- F. Lever 5: TOON replies and dropping unused fields (Code Example 4)
- G. Measuring every call (Code Example 5)
- H. Two more levers outside your prompt: Batch API and context caching
You can check the other blogs in this series on the links below:
- Part 1: This article
- Part 2: Evaluating an LLM vision pipeline honestly: baselines, label traps and run-to-run noise
A. Where do multimodal tokens actually come from?
Every Gemini call is billed on its input tokens (what you send) and its output tokens (what the model generates) (token counting docs: About tokens). In a vision pipeline, they break down like this.
Input tokens: what you send
- Text: your prompt, instructions and the listing text.
- Images: on Gemini 3 and Gemini 4, a budget per image set by the media resolution setting (section B), not by the file size of the JPEG.
- System instructions and tool definitions: counted as input too, so a long system prompt is paid on every call.
- Cached input: the part of the input that repeats a long prefix from an earlier request. It is still input, but billed at a lower rate (section H).
- Tool results: if the model calls tools such as Google Search or code execution, what they bring back is counted as well. This pipeline uses none.
Output tokens: what the model generates
- The reply: the answer you read, in our case the TOON table (section F).
- Thinking: the model’s internal reasoning before it replies. You don’t see it in the answer, but it is billed with the output and counts against max_output_tokens. Most current Gemini 3 and Gemini 4 models think by default, so this cost appears even if you never asked for it. Section E shows how to tune it per step; in my runs, at the lowest level, it was zero.
And one cost that doubles both: retries. A reply that comes back but fails to parse has already been billed, input and output. The retry pays the full input again, plus a new output. That is why the cut-off JSON replies in section F were so costly.

Video, audio and PDFs have their own token rates; this post covers images only.

In the match check, images are about two thirds of the input. That is why the first lever is resolution, not the prompt.
B. Lever 1: Choose the resolution per step, not per pipeline
Gemini’s media_resolution setting decides how many tokens each image becomes. For Gemini 3 and Gemini 4 models, the media resolution docs (Token counts table) list roughly:
- low: about 280 tokens per image
- medium: about 560 tokens per image
- high, and the default when you set nothing: about 1,120 tokens per image
- ultra_high: about 2,240 tokens per image, available only per image (Available resolution values)
The default is the high setting, so a pipeline that never sets media_resolution pays the top price for every photo. My measured numbers matched the docs closely: about 270 tokens per image at LOW and about 540 at MEDIUM, over more than 20,000 images.

The key insight is that different steps need different detail:
- “Is this a product photo or a size chart? Is it blurry?” is a coarse question. LOW is enough.
- “Is the logo, the pattern, the exact shade of blue the same as the listing says?” needs detail. MEDIUM.

Code Example 1: resolution per step. In code, it is one dictionary:
from google import genai
from google.genai import types
client = genai.Client()
RESOLUTION = {
"photo_check": types.MediaResolution.MEDIA_RESOLUTION_LOW, # what is in each photo?
"match": types.MediaResolution.MEDIA_RESOLUTION_MEDIUM, # does it match the listing?
}
def call(step, prompt, image_parts):
config = types.GenerateContentConfig(
media_resolution=RESOLUTION[step],
max_output_tokens=256,
)
return client.models.generate_content(
model="gemini-3.5-flash-lite", # or another Gemini 3 / Gemini 4 model
contents=[*image_parts, prompt],
config=config,
)
Definitions of the Components:
- media_resolution: the token budget per image. MEDIA_RESOLUTION_LOW, MEDIA_RESOLUTION_MEDIUM or MEDIA_RESOLUTION_HIGH. If it is unset, the model’s default applies, which on Gemini 3 and Gemini 4 is the high budget.
- max_output_tokens: a hard cap on the reply. A reply that reaches it is cut off, and finish_reason becomes MAX_TOKENS. On thinking models the cap includes thinking tokens, so a small cap only works with low thinking (section E).
- No temperature: starting with Gemini 3.6 Flash and 3.5 Flash-Lite, temperature, top_p and top_k are deprecated and ignored, and future models will reject them with an error. For consistent answers, Google recommends explicit rules in a system instruction; the fixed reply layout in section F does that job here.
- contents: the image parts followed by the prompt text. The order is the order the model sees them in.
Tip: Gemini 3 and Gemini 4 models also let you set the resolution per image inside one request (Per-content-item media resolution). That helps when one photo needs detail (a close-up of a label) and the rest do not.
A word of caution: don’t drop resolution blindly. Token cost per image is the same on Gemini 3 and Gemini 4, but how well each model reads a photo at a given setting can differ. Google itself recommends high for most image analysis and says to always test and evaluate the settings on your application. Test each step at the lower setting against labelled examples before switching. Keep the match check at MEDIUM or higher, because that is where fine details decide the answer.
C. Lever 2: Cache what does not depend on what you are testing
When you build a pipeline like this, you change the match step again and again: a new prompt version, another field, a different resolution. Each time, you re-run the same listings.
The photo check looks only at the photos. It never reads the listing text or the match prompt, so its answer stays the same however often you change the match step. Yet without a cache, every re-run pays for the photo check again.

What does the answer depend on? Three things: the photos themselves, in order; the model; and the photo-check prompt and resolution. Key the cache on exactly those:
- Use the photo bytes, not file names. Two listings that share a photo under different names should share the answer, and a photo replaced under the same name should not.
- Include the call settings. If you edit the photo-check prompt or change the model, the old answers are stale, and the key has to change with them.
Code Example 2: a cache keyed on what the answer depends on.
import copy, hashlib, threading
from pathlib import Path
_cache, _lock = {}, threading.Lock()
def sha(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()[:16]
def cache_key(settings, photos):
# settings = model + resolution + prompt; photos in order (the reply refers to them by position)
photo_hashes = [sha(Path(p).read_bytes()) for p in photos]
return sha((settings + "|" + ",".join(photo_hashes)).encode())
def check_photos(settings, photos, run_photo_check):
key = cache_key(settings, photos)
with _lock:
if key in _cache:
return copy.deepcopy(_cache[key]) # callers may change their copy
result = run_photo_check(photos) # the LOW-resolution Gemini call
with _lock:
_cache[key] = copy.deepcopy(result)
return result
With three versions of the match prompt under test, the photo check runs once instead of three times. For our 8-photo listing that is about 3,010 tokens instead of 9,030.
The general rule is: before every model call, ask what the answer depends on. If the answer has been computed before for the same inputs, don’t pay for it again.
D. Lever 3: One call for all photos, not one call per photo
The natural first version of the photo check sends one photo per call: “what does this photo show, and is it usable?”. For eight photos that is eight calls, and every call repeats the same instructions and pays its own request overhead.
Gemini accepts several images in one request (Image understanding: Prompting with multiple images). So send all photos in one LOW-resolution call and ask for one row per photo. A small TOON table (more on TOON in section F) keeps the reply short.
Code Example 3: one photo-check call for all photos.
def photo_check_prompt(n):
# f-string: {n} is filled in, {{ }} prints a literal { }
return f"""You are given {n} photos from one product listing, numbered 1 to {n} in the order shown.
For each photo, say what it shows and whether it is good enough for a product page.
Reply in TOON and nothing else. Layout (example values):
photos[{n}]{{photo,kind,usable,problem}}:
1,PRODUCT,yes,
2,PRODUCT,no,blurry
3,SIZE_CHART,no,not a product photo
kind is one of PRODUCT, SIZE_CHART, BANNER, PACKAGING, OTHER. One row per photo, in order."""
One detail makes this robust in production: validate the reply before you use it. Check that there is exactly one row per photo and that every photo number is in range. A reply with a missing row is a parse failure to retry, not a gap to guess around:
def parse_photo_rows(reply, n):
rows = {}
for r in decode_reply(reply).get("photos", []): # decode_reply: see section F
if str(r.get("photo", "")).isdigit() and 1 <= int(r["photo"]) <= n:
rows[int(r["photo"])] = r
if len(rows) != n:
raise ValueError(f"photo check returned {len(rows)} of {n} rows") # retry
return rows
Result: for an 8-photo listing, eight calls become one. That saves about 2,750 tokens of repeated instructions per listing, plus seven request round trips.

Don’t overdo it. A batch works when every photo gets the same, simple question. Putting dozens of photos or several different questions into one call makes each answer less reliable. Batch per listing, and check the per-photo answers against a few labelled examples.
E. Lever 4: Trim the prompt and stop asking the model to do code’s job
Prompts grow quietly. Every edge case adds a rule, every new field adds a line, and after a few weeks no one remembers why half of it is there. Three changes help:
- Send only the listing fields the model needs. Sending the full product specification is tempting. Often only a few fields help the decision.
- Move arithmetic out of the model. If you ask the model for a confidence score or an action (“approve”, “flag”), consider computing both in Python from what the model has already said. That is fewer output tokens, a deterministic result and easy to change later.
- Match thinking to the task, then test it. Thinking is the model reasoning before it answers. It can improve hard decisions, like a subtle colour shade or a logo half hidden in the photo, but every thinking token is billed with the output, adds latency, and counts against max_output_tokens. So treat it as a dial per step, not an on/off switch.

Google’s own guidance gives a sensible starting point: use minimal or low thinking for classification, the default for moderate tasks, and the highest level for complex multi-step problems. For Gemini 3.5 Flash-Lite, the migration guide is more specific: leave thinking_level at minimal for high-volume extraction, routing or classification, and raise it to medium or high for multi-step reasoning.
The photo check is a plain classification, so it starts at the lowest level. The match check is a judgement call, so it is worth testing at more than one level:
THINKING = {
"photo_check": "minimal", # classification: lowest level is usually enough
"match": "low", # try minimal, low and medium on labelled listings
}
config = types.GenerateContentConfig(
media_resolution=RESOLUTION[step],
thinking_config=types.ThinkingConfig(thinking_level=THINKING[step]),
)
How to choose: run the same labelled listings at two or three levels, and compare accuracy, thinking tokens and latency for each. Keep the lowest level that does not lose accuracy you care about. If you raise thinking, raise max_output_tokens too, or replies may be cut off. The levels differ by model: minimal exists on models such as Gemini 3.5 Flash-Lite and 3.6 Flash, while Gemini 3.8 Flash and Gemini 4 Argon start at low (see the levels table). In my runs the lowest level was enough for both steps, and thinking tokens were zero.
An honest note: within a couple of weeks of trimming, my prompt had started growing again as new rules were added. Trimming is not a one-time task. Track prompt size per version, the same way you track latency.
F. Lever 5: TOON, and the fields you stop asking for
This lever came out of a real trade-off. I started the way most people do: Gemini’s structured output, with a response_schema describing the reply. It was perfectly consistent; every reply parsed.
The catch is that a schema-enforced reply is JSON, and JSON is wordy: every field name, quote, brace and comma is an output token you pay for. My calls also ran with a hard cap on output tokens per call, and the full JSON reply did not fit under it. It was cut off mid-object and failed to parse, and every cut-off was a billed call that had to be retried. Raising the cap was not an option, and a consistent reply that does not fit is no use.
So I changed the reply format to TOON, and dropped the fields nothing read (more on that at the end of this section). In my experiments the reply used far fewer output tokens, fit under the cap, and was consistent nearly every time.

TOON (Token-Oriented Object Notation) is a compact, open format for the JSON data model, defined in an open specification. Arrays of uniform objects become small tables: the field list is declared once in the header, then one row per element:
fields[4]{field,photo,listing,same}:
product type,ankle boot,ankle boot,yes
colour,black,navy blue,no
pattern,plain,plain,yes
logo,small metal tag,,
issues[2]:
- listing says navy blue, photos show black
- photo 4 is a size chart, not the product
summary: black ankle boot shown from four angles
verdict: MISMATCH
The same content in JSON repeats “field”, “photo”, “listing” and “same” four times, and adds braces, quotes and commas on every line.
TOON is not always smaller: its own README says that for deeply nested or non-uniform data compact JSON often wins. A flat, fixed reply like ours is its sweet spot.
Who actually writes the TOON? The model does. TOON is a format, not a Gemini feature: there is no “reply in TOON” switch in the API. Gemini’s structured output can enforce a JSON Schema, but only for JSON. So you ask for TOON in the prompt, show the exact layout, and the model writes it as plain text. The toon-format library then runs on your side: decode() turns the reply back into a Python dict (and encode() goes the other way, which is the library’s main use: compact data for LLM prompts).
So the trade-off is explicit. Structured output gives you a guarantee: the API enforces the shape and every reply parses, but you pay for JSON’s extra tokens. TOON saves those tokens, but it is only as reliable as the model’s instruction following, so you have to check the reply. In my case the output cap decided it: the schema reply did not fit, TOON did, and about 99.8% of TOON replies decoded on the first try (more below). If your replies fit comfortably under your cap and output tokens are not a big part of your bill, structured output is the simpler choice.
How to make the model write the same format every time. You can’t force it, so you stack a few layers. First, the prompt:
- Show the exact layout with example values, and say “Reply in TOON and nothing else”.
- Order the fields: comparison first, verdict last. The model writes what it compared before it commits to an answer.
- Say how to write an empty value. For example: leave listing empty when the listing does not mention the field.
- List the allowed values. “kind is one of PRODUCT, SIZE_CHART, BANNER, PACKAGING, OTHER” leaves the model nothing to invent.
- Keep the format rules fixed. Put them in a system instruction that never changes between calls; Google recommends explicit rules in a system instruction as the way to improve determinism. Keep the reply short and flat.
Code Example 4: decode TOON locally, so the rest of your code still works with ordinary Python dicts:
import re, toon_format # pip install toon-format
FENCE = re.compile(r"^\s*```[a-zA-Z]*\s*\n|\n\s*```\s*$")
def decode_reply(text):
cleaned = pad_short_rows(FENCE.sub("", text.strip()))
try:
return toon_format.decode(cleaned)
except Exception as exc:
raise ValueError(f"TOON decode failed: {exc}") from exc # let the caller retry
The one slip worth handling: models sometimes drop a trailing empty value. They write logo,small metal tag instead of logo,small metal tag,,, and the strict decoder rejects the row with an error like “Expected 4 values but found 2”. Each failed parse is a wasted, billed call. A small pre-pass adds the missing commas:
TABLE_HEADER = re.compile(r"^(\s*)[A-Za-z_]\w*\[\d+\]\{([^}]*)\}:\s*$")
def pad_short_rows(text):
out, expected, indent = [], None, 0
for line in text.split("\n"):
m = TABLE_HEADER.match(line)
if m:
expected, indent = len(m.group(2).split(",")), len(m.group(1))
elif expected is not None:
if line.strip() and len(line) - len(line.lstrip()) > indent:
line += "," * max(0, expected - 1 - line.count(","))
else:
expected = None
out.append(line)
return "\n".join(out)
Then check, don’t trust. After decoding, validate what your code depends on: the number of rows (TOON’s [n] header makes a missing row easy to spot), the allowed values, and the verdict. Anything that fails is retried once with the same input. If it fails again, the item goes to REVIEW instead of guessing. And if one step keeps failing, switch just that step to JSON with a JSON Schema, which the API enforces.

Measure it. Log whether every reply decoded and how long it was. In my production runs, about 99.8% of the 13,500 TOON replies decoded on the first try (the rest were caught by the retry), replies settled at a median of about 200 output tokens, and only about 1 in 6,000 reached the cap.
The honest part: TOON alone is not where most of the saving came from. For exactly the same fields, compact JSON is about 50% larger than TOON. The bigger saving was the fields I stopped asking for: a detail note per field, a model-written confidence, an action hint and long free-text notes. TOON then pushed what remained comfortably under the cap.

Takeaway: before switching formats, list every output field and ask “does any code read this?” Delete what nothing reads, then compress what is left.
G. Measure every call, or you are guessing
None of the levers above would have been visible without a token log. Every response carries a usage_metadata block with the token counts split by modality, plus thinking and cached tokens. Log one JSON line per call, with the resolution, the image count, text, image, output and cached tokens, whether the reply was truncated, and the latency.
Code Example 5: a token log line per call.
import json
def log_usage(step, listing_id, n_images, resp, seconds):
u = resp.usage_metadata
by_modality = {str(d.modality).split(".")[-1]: d.token_count
for d in (u.prompt_tokens_details or [])}
line = {
"listing": listing_id, "step": step,
"resolution": RESOLUTION[step].name, "n_images": n_images,
"text_tokens": by_modality.get("TEXT", 0),
"image_tokens": by_modality.get("IMAGE", 0),
"output_tokens": u.candidates_token_count or 0,
"thinking_tokens": u.thoughts_token_count or 0,
"cached_tokens": u.cached_content_token_count or 0,
"truncated": str(resp.candidates[0].finish_reason).endswith("MAX_TOKENS"),
"seconds": round(seconds, 2),
}
with open("token_usage.jsonl", "a") as f:
f.write(json.dumps(line) + "\n")
A short report script then answers the questions that matter: tokens per image at each resolution, tokens per listing, thinking tokens per step, and how many replies were truncated. Every measured number in this post came from a file like this.
H. Two more levers outside your prompt
Everything above reduces the number of tokens. Gemini also has two ways to reduce the price of the tokens you still send.
1. Batch API: half the price, if you can wait. The Gemini Batch API runs requests asynchronously at 50% of the standard price, with a target turnaround of 24 hours (often much faster). A listing audit that runs overnight, before listings go live, is a natural fit. A seller waiting on screen for an answer is not.
2. Context caching: check that your prompts qualify. Gemini applies implicit caching automatically when requests share a long identical prefix, and passes on the saving. The prefix must be long, though: the documentation lists a minimum of 4,096 tokens for Gemini 4 Argon and recent Gemini 3 Flash models. A short audit prompt with different photos in every request rarely qualifies. In my logs, well under 1% of input tokens were cache hits. That is why the application-level cache in section C matters: it works whatever the prompt length.
Cache hits show up in each response’s usage metadata as cached_content_token_count, which the token log in section G already records.
Putting it together
Applied one at a time to the 8-photo listing, the levers stack up like this:

Together, the five levers take one listing from about 21.7K to 8.3K tokens, 62% less, before any Batch API discount. On Gemini 3 and Gemini 4, resolution is the biggest lever, followed by one call for all photos. The others are smaller one by one, but they add up, and three of them (batching, trimming, TOON) also make the pipeline faster and more reliable.
The design itself is the last lever. The chart in section A shows two designs for the same listing:
- Photo check → match check (2 calls): about 8.3K tokens.
- One combined call with all 8 photos: about 6.5K tokens.
The combined call is cheaper, but you lose the per-photo results (which photo is blurry, which one is a size chart), and the model has to ignore unusable photos and compare in the same answer. If you need photo-level feedback for sellers, or many listings carry non-product photos, two steps are worth the extra tokens. Measure accuracy and tokens together on your own data before choosing.
Key takeaways
- Image tokens are set by media_resolution, not by file size, and the default is the most expensive setting. Choose it per step: LOW for coarse questions (“is this a product photo?”), MEDIUM or higher for fine detail (“is this the same logo?”).
- Cache any result that does not depend on the variable you are changing, and key it on what the answer depends on: the content and the call settings.
- Ask about all photos in one call, not one call per photo. Validate that every photo has a row before you use the reply.
- Trim the prompt, move arithmetic into code, and tune thinking per step: start low, test higher levels on labelled examples, and keep the lowest one that holds accuracy.
- List every output field and delete the ones nothing reads. Then use a compact format like TOON for what remains.
- Log every call. You cannot optimise what you do not measure.
- Then lower the price of what is left: use the Batch API for work that can wait, and check whether your prompts are long enough to benefit from context caching.
What’s next
In the next part we will be discussing evaluating an LLM vision pipeline honestly: trivial baselines, how to score “not sure”, label traps, fair experiments and run-to-run noise. Cutting cost is only half the job; the other half is knowing the cheaper pipeline is still right.
The companion GitHub repository, gemini-vision-on-a-budget, contains the complete, runnable code from this post:
- scripts/estimate_costs.py reproduces every estimate in this post offline, without an API key.
- scripts/fetch_abo_sample.py downloads a small ABO sample, and scripts/run_audit.py runs both designs with real Gemini calls.
- scripts/cost_report.py turns your own token log into the measured numbers.
Where the numbers come from
- Estimates (the charts in sections A and “Putting it together”, and the savings per lever) assume thinking at the lowest level (no thinking tokens; raising it adds output tokens), and use the per-image budgets in the Gemini 3 and Gemini 4 documentation, plus assumed prompt and reply sizes. The companion repo’s scripts/estimate_costs.py reproduces every one of them, and its assumptions are listed in vision_budget/estimate.py.
- Measured numbers (about 270 and 540 tokens per image, a median of about 200 output tokens, about 1 reply in 6,000 reaching the cap, about 99.8% of TOON replies decoding on the first try, and cache hits well under 1% of input tokens) are my own measurements from about 23,000 Gemini 3.5 Flash-Lite calls, logged while running the pipeline in production on a small subset of the workload. They are observed results, not benchmarks, and your numbers will differ with your model, prompts and photos.
- Models: I measured on Gemini 3.5 Flash-Lite. The estimates use the documented image budgets for Gemini 3 and Gemini 4, which are the same for both, and my 3.5 Flash-Lite measurements match them. Check the media resolution Token counts table and the thinking levels table for your model’s exact budgets and lowest thinking level.
- Image tokens in Google’s docs: the Token counting and Image understanding pages still describe an older rule of 258 tokens per 768×768 tile. The estimates use the model-specific media resolution table instead, which my measurements match: at LOW every photo came in at about 250–280 tokens, and at MEDIUM about 520–550, whatever its size.
References
Links go to the exact section of each page. Some links highlight the quoted sentence directly (most current browsers support this).
- Google, Gemini API, Media resolution: Token counts (per-image budgets for Gemini 3 and Gemini 4), Available resolution values, Per-content-item media resolution, Choosing the right resolution.
- Google, Gemini API, Token counting: About tokens, Context window, the older image tile rule.
- Google, Gemini API, Image understanding: Prompting with multiple images, Token calculation.
- Google, Gemini API, Thinking: Controlling thinking (levels per model), Token limits and max_output_tokens, Pricing, Best practices.
- Google, Gemini API, What’s new in Gemini 3.6 Flash and 3.5 Flash-Lite: sampling parameter deprecation, determinism through system instructions, thinking level for 3.5 Flash-Lite.
- Google, Gemini API reference, generateContent: UsageMetadata, FinishReason.
- Google, Gemini API: Batch API, price and turnaround; Context caching, implicit caching and minimum prefix lengths; Pricing.
- Google, Gemini API: Structured output (JSON Schema only).
- TOON: toon-format/toon (tabular form, when not to use it) and the toon-format/spec specification.
- Amazon Berkeley Objects dataset: project page, licence and download (CC BY 4.0, credit Amazon.com). Paper: Collins et al., ABO: Dataset and Benchmarks for Real-World 3D Object Understanding, CVPR 2022.
Read my other articles on Medium. Please post your comments, queries or suggestions here, or connect with me on LinkedIn or GitHub. I’d love to hear which lever saved you the most.
Gemini Vision on a Budget: Five Levers that Cut Multimodal Token Cost in Production was originally published in Google Cloud – Community on Medium, where people are continuing the conversation by highlighting and responding to this story.
Source Credit: https://medium.com/google-cloud/gemini-vision-on-a-budget-five-levers-that-cut-multimodal-token-cost-in-production-29c2615e1f28?source=rss—-e52cf94d98af—4
