Google logo

Gemma 4 26B A4B

Gemmav26B A4BCurrent
byGoogleGoogle(enterprise)
Released April 3, 2026
Context262.1K tokens
Price (In / Out)$0.08/M / $0.35/M
CategoryMultimodal LLM

About Gemma 4 26B A4B

Gemma 4 26B A4B is a multimodal llm from Google. Supports up to 262,144 token context window. Available from $0.08/M input tokens.

Capabilities

textvisionvideocode

Input Modalities

imagetextvideo

Output Modalities

text

Technical Details

API Identifier
google/gemma-4-26b-a4b-it
Category
Multimodal LLM
Context Window
262,144 tokens

Tags

multimodalvideobudget-friendlylong-context

Run this model yourself

Local and cloud setup for Gemma 4 26B A4B, with exact configurations, sources and clear evidence limits.

Find a model for your hardware
Local hardwareDocumented setupSources checked Oct 17, 2026

Run complete native Gemma 4 26B-A4B text, image and video checks on a CPU workstation

Load the complete publisher-native Gemma 4 26B-A4B instruction checkpoint in CPU FP32 using the released Transformers runtime. A private serial harness runs a grounded text question, an original RGB geometry image and a four-frame moving-object video through the native template and processors. Every expanded input is bounded to 3,840 tokens with up to 256 new tokens inside a 4,096-token configured sequence. The 256 GiB RAM and 400 GiB disk allocation is unmeasured; no fit, speed or model-quality result is claimed.

Hardware
Intel Xeon w5-2465X / ASUS W790E-SAGE SE,256GiB RAM,400GiB free disk
Runtime
Native Gemma 4 full multimodal CPU Transformers 5.11.0; Torch 2.11.0 CPU; torchvision 0.26.0 CPU; Python 3.12 · CPU
Model format
Safetensors · All complete native floating parameters loaded as CPU FP32; publisher stored dtype BF16 · Unquantized publisher BF16 checkpoint; reader explicitly loads all floating model parameters as CPU FP32
Workload
4,096 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an existing Intel Xeon w5-2465X / ASUS W790E-SAGE SE workstation with Ubuntu 24.04 x86_64, 256 GiB RAM, 400 GiB free disk and 16 allocated CPU threads. These are planning allocations, not measured minima.
  • Python 3.12 and the exact CPU Torch 2.11.0 / torchvision 0.26.0 wheels are selected for this released Transformers 5.11.0 route. No CUDA, Flash Attention, grouped-matrix custom kernels, media codec, audio dependency or remote code is required for the explicit native eager path. Save the resolved environment and stop on pip check or import failures.
  • Review the exact native Apache 2 model grant and publisher responsible-use guidance. Use the complete Google snapshot; do not substitute a smaller, Diffusion, GGUF or text-only model. No model operations, rights acceptance or suitability review was performed by the author.
  • Only three fixed jobs are accepted: a short grounded text question, an original geometry image and four original RGB frames with explicit one-frame-per-second authored timing. These are controlled reader-generated inputs, not third-party media, recorded video, benchmark evidence or a quality guarantee.
  • The frozen ordinary catalog canonical is mapped to this explicit native checkpoint as a documented deployment choice, not byte equivalence to provider serving. The separate :free canonical remains identity-qualified separately; this pair does not assert free endpoint availability or merge canonicals.

Exact model and requirements

Artifact:
Google / Gemma 4 26B-A4B instruction-tuned complete native multimodal checkpoint · checkpoint google/gemma-4-26B-A4B-it
Publisher revision:
4d7ae4984b7db7de8f8457170b3f1a419ee76d52
Artifact digest:
Two separately hashed native shards form the complete weights; no invented composition digest.
Download size:
48.07 GiB
Memory requirement (unknown):
Unknown — Full CPU FP32 load, attention/cache, image/video tensors, buffers and process peak are unmeasured.
System RAM / disk:
Unknown / Unknown
Placement:
single device. Two complete on-disk Safetensors parts load one native model on one CPU host; no tensor or pipeline sharding. One CPU host, full integrated language and vision model; no accelerator, device map, quantization or component offload.
KV cache:
Native FP32 eager attention cache follows the explicitly FP32 CPU model. Thirty layers mix five sliding-window attention layers with one global-attention layer per six-layer group; local/global head layouts differ. Exact cache/process peak is unmeasured.
Workload:
4,096 token context; Unknown; Unknown; concurrency 1; batch 1; cache cold; repetitions Unknown.
Tokenizer:
Exact native Gemma tokenizer, full standalone Jinja and native image/video processors · 4d7ae4984b7db7de8f8457170b3f1a419ee76d52
Sampling / reasoning:
Author-selected deterministic greedy decoding, do_sample=False, max_new_tokens=256, batch/concurrency 1. Native sampling defaults are temperature 1.0, top-k 64 and top-p 0.95; they are inactive under this explicit greedy override. Native final EOS IDs 1 and 106 are required; tool handoff ID 50 stops generation but is rejected as a non-final result. Native enable_thinking=False renders the publisher empty thought-channel prefix. Unexpected thought/tool/control output is rejected instead of silently stripped. Native autoregressive full-model text, image and video handling is retained; no Diffusion or text-only substitution, tools, audio or agent execution.
Runtime prerequisites:
Ubuntu 24.04 x86_64; See prerequisites above.

Official artifact · License

The exact native Google model card declares Apache License 2.0 and links to the archived actual Apache 2 grant. Preserve the license, copyright, attribution and NOTICE obligations, identify modifications and observe patent/termination and warranty conditions. This exact full Gemma 4 checkpoint is not Gemma Diffusion or a prior restricted Gemma release; no terms acceptance or legal clearance is performed here. Publisher safety and responsible-use guidance still matters; this controlled demonstrator does not establish safety or suitability.

  • Complete serialized native weights total 51,612,009,916 bytes across both shards. API BF16 scalar metadata counts 25,805,936,206 elements, which would occupy 103,223,744,824 bytes if all FP32; this is a parameter-storage calculation, not resident-memory or peak fit proof.
  • Index metadata separately reports total_parameters 26,544,131,376 and total_size 51,611,872,412. Those fields differ from API dtype scalar counts and serialized bytes; none is silently substituted for measured RAM.
  • 256 GiB system RAM, 400 GiB free disk and 16 runtime threads are selected planning allocations. Loading, the complete vision tower, hybrid sliding/global cache, 4K inputs, dependency environment and OS add unknown overhead. No active-parameter shortcut or sibling fit/speed transfer.

One-time setup and hardware

hardware
Unknown — Existing desktop purchase price and incremental hardware cost depend on the reader; unknown.
Existing desktop purchase price and incremental hardware cost depend on the reader; unknown. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

electricity
Unknown — Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion.
Actual wall power, electricity rate and powered hours are unknown; no TDP-to-wall-power conversion. Tax: unknown.
storage
Unknown — Incremental cost of local disk capacity is unknown. The 400 GiB free-disk walkthrough allocation is an author choice, not a measured requirement.
Incremental local400GiB available disk cost is unknown; this is an allocation, not a measured minimum. Tax: unknown.
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Install the source-qualified CPU environment

    Install only in a dedicated virtual environment. Wheel URL hashes pin both CPU artifacts without changing the publisher model. Other explicit direct pins satisfy the archived released dependency constraints; transitive and system packages resolve at reader install and must be recorded. No installation was executed by this author.

    Command
    set -e
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv curl ca-certificates openssl
    mkdir -p "$HOME/gemma4-26b-native"
    cd "$HOME/gemma4-26b-native"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl#sha256=f82e2ae20c1545bb03997d1cc3143d94e14b800038669ee1aca45808a9acc338' 'https://download-r2.pytorch.org/whl/cpu/torchvision-0.26.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl#sha256=cf547dc0975eb40bc3249be4ccbeb736597d2c3ece305b1c4e5b7a5dd7363567'
    .venv/bin/python -m pip install transformers==5.11.0 huggingface-hub==1.5.0 tokenizers==0.22.2 regex==2025.10.22 numpy==2.2.3 Pillow==11.1.0 safetensors==0.5.3
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > installed-requirements.txt

    Expected result: The CPU wheels, exact direct versions and dependency consistency checks succeed; preserve the resolved lock output and stop on failure.

Download the model

  1. 1. Write the exact complete native manifest

    All ten runtime/card/config/tokenizer/weight files are retained. Both weight bodies and tokenizer are downloaded only by the reader. SHA-256 LFS content hashes and native Git blob identities are distinct and explicitly verified; no unqualified mutable main downloads.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat > artifact-manifest.json <<'MANIFEST'
    {
      "repo": "google/gemma-4-26B-A4B-it",
      "revision": "4d7ae4984b7db7de8f8457170b3f1a419ee76d52",
      "files": [
        {
          "path": "README.md",
          "bytes": 27979,
          "algorithm": "git-sha1",
          "digest": "742346e1fe57997c831b9065f4c54a9416021526"
        },
        {
          "path": "chat_template.jinja",
          "bytes": 18683,
          "algorithm": "git-sha1",
          "digest": "4741bf6e4132ba23a5537f9d6e74e9a6d613d7cd"
        },
        {
          "path": "config.json",
          "bytes": 3815,
          "algorithm": "git-sha1",
          "digest": "f42adcca257bb0865c506947671e7d0af52ac9c4"
        },
        {
          "path": "generation_config.json",
          "bytes": 208,
          "algorithm": "git-sha1",
          "digest": "e605bb4523b1462ea9d9a3810b9e3ecf7ab7b1f6"
        },
        {
          "path": "model-00001-of-00002.safetensors",
          "bytes": 49907246508,
          "algorithm": "sha256",
          "digest": "1127684971bbca40465435a5cad69d67ad603bf5e61c6dfd5561fae4a3bcfdb3"
        },
        {
          "path": "model-00002-of-00002.safetensors",
          "bytes": 1704763408,
          "algorithm": "sha256",
          "digest": "aab47033e1e8a492ef8e581efae1cf36478d0433567e7729b3c1728bc8970db7"
        },
        {
          "path": "model.safetensors.index.json",
          "bytes": 103196,
          "algorithm": "git-sha1",
          "digest": "889ab10e12aca96c43c9804a041fb1780de1e5ca"
        },
        {
          "path": "processor_config.json",
          "bytes": 1689,
          "algorithm": "git-sha1",
          "digest": "5465974d23e1eca2c46c2809b26c997946ce0d90"
        },
        {
          "path": "tokenizer.json",
          "bytes": 32169626,
          "algorithm": "sha256",
          "digest": "cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f"
        },
        {
          "path": "tokenizer_config.json",
          "bytes": 3082,
          "algorithm": "git-sha1",
          "digest": "6068e357379d36f823c377e30efb101fa2c67fe4"
        }
      ]
    }
    MANIFEST
    cat > reader-download.py <<'PYDOWNLOAD'
    import hashlib,json,pathlib,urllib.request
    root=pathlib.Path('model');root.mkdir(exist_ok=True)
    manifest=json.load(open('artifact-manifest.json'))
    base='https://huggingface.co/'+manifest['repo']+'/resolve/'+manifest['revision']+'/'
    for row in manifest['files']:
     path=root/row['path'];path.parent.mkdir(parents=True,exist_ok=True)
     if not path.exists():
      temporary=path.with_name(path.name+'.partial')
      with urllib.request.urlopen(base+row['path'],timeout=120) as src,temporary.open('wb') as dst:
       for chunk in iter(lambda:src.read(1024*1024),b''):dst.write(chunk)
      temporary.replace(path)
     if path.stat().st_size!=row['bytes']:raise SystemExit('wrong size: '+row['path'])
     digest=hashlib.sha256() if row['algorithm']=='sha256' else hashlib.sha1()
     if row['algorithm']=='git-sha1':digest.update(b'blob '+str(row['bytes']).encode()+b'\0')
     with path.open('rb')as src:
      for chunk in iter(lambda:src.read(1024*1024),b''):digest.update(chunk)
     if digest.hexdigest()!=row['digest']:raise SystemExit('wrong digest: '+row['path'])
    index=json.load(open(root/'model.safetensors.index.json'))
    assert set(index['weight_map'].values())=={'model-00001-of-00002.safetensors','model-00002-of-00002.safetensors'}
    assert sum(x['bytes']for x in manifest['files']if x['path'].endswith('.safetensors'))==51612009916
    print('All ten pinned native files verified; two complete model shards retained.')
    PYDOWNLOAD
    .venv/bin/python reader-download.py

    Expected result: All ten files match their exact pinned sizes and SHA-256 or Git blob identity; the complete two-shard index set is checked before any model import. Stop on mismatch.

Configure

  1. 1. Create a stable private key

    Create the reader-generated secret only when absent, keep it private and refuse an empty existing file. No key is generated or executed by the author.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    umask 077
    if [ ! -e .api-key ]; then openssl rand -hex 32 > .api-key; fi
    test -s .api-key
    chmod 600 .api-key

    Expected result: A stable private 64-character hexadecimal key exists with restricted permissions; later reader startup checks its exact format.

  2. 2. Write strict output guards

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat > multimodal_server.py <<'PYCODE'
    """Reader-authored private Gemma4 full-native educational harness; not publisher server."""
    import hashlib
    import hmac
    import json
    import math
    import pathlib
    from http.server import BaseHTTPRequestHandler, HTTPServer
    ROOT = pathlib.Path(__file__).resolve().parent
    PORT = 9006
    PIN = '4d7ae4984b7db7de8f8457170b3f1a419ee76d52'
    PROMPTS = {'text':'The library opens at 09:00 and closes at 17:00 on the same day. How many hours is it open? Answer briefly.',
    'image':'Describe the visible colors and shapes in this original geometry image. Answer briefly.',
    'video':'Describe how the red rectangle changes position from the first frame to the last. Answer briefly; do not invent events outside the frames.'}
    
    def validate_result(job, d):
        if type(d) is not dict or set(d) != {'job','text','input_tokens','output_tokens','media_tokens','frames','stop_id'}:
            raise ValueError('result_schema')
        if d['job'] != job or type(d['text']) is not str or not d['text'].strip() or len(d['text'])>16384:
            raise ValueError('result_text')
        for k in ('input_tokens','output_tokens','media_tokens','frames','stop_id'):
            if type(d[k]) is not int:
                raise ValueError('result_integer')
        if not 1<=d['input_tokens']<=3840 or not 1<=d['output_tokens']<=256 or d['input_tokens']+d['output_tokens']>4096:
            raise ValueError('result_context')
        if d['stop_id'] not in (1,106) or d['frames'] != (4 if job=='video' else 0):
            raise ValueError('result_stop_or_frames')
        if (job=='text' and d['media_tokens']!=0) or (job=='image' and not 1<=d['media_tokens']<=70) or (job=='video' and not 4<=d['media_tokens']<=280):
            raise ValueError('result_media')
        if any(s in d['text'] for s in ('<|','|>','<channel|>','<tool_call|>','<tool_response|>','<turn|>','<eos>','<bos>')):
            raise ValueError('unexpected_native_control')
        return d
    
    def check_loading(info):
        expected={'missing_keys','unexpected_keys','mismatched_keys','error_msgs'}
        if type(info) is not dict or set(info)!=expected or any(info[k] for k in expected):
            raise RuntimeError('incomplete_or_incompatible_checkpoint')
    
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  3. 3. Write full native CPU adapter

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat >> multimodal_server.py <<'PYCODE'
    def make_engine():
        # Only the reader invokes this path. Fake protocol tests never import native libraries.
        model_dir=ROOT/'model'
        manifest=json.loads((ROOT/'artifact-manifest.json').read_text())
        for row in manifest['files']:
            path=model_dir/row['path']
            if path.stat().st_size!=row['bytes']: raise RuntimeError('artifact_size')
            digest=hashlib.sha256() if row['algorithm']=='sha256' else hashlib.sha1()
            if row['algorithm']=='git-sha1': digest.update(b'blob '+str(row['bytes']).encode()+b'\0')
            with path.open('rb') as handle:
                for chunk in iter(lambda:handle.read(1024*1024),b''): digest.update(chunk)
            actual=digest.hexdigest()
            if actual!=row['digest']: raise RuntimeError('artifact_hash')
        config=json.loads((model_dir/'config.json').read_text())
        if config['architectures']!=['Gemma4ForConditionalGeneration'] or config.get('audio_config') is not None:
            raise RuntimeError('wrong_native_architecture')
        import numpy as np
        import torch
        from PIL import Image, ImageDraw
        from transformers import AutoProcessor, Gemma4ForConditionalGeneration, LogitsProcessor, LogitsProcessorList
        from transformers.video_utils import VideoMetadata
        torch.set_num_threads(16)
        processor=AutoProcessor.from_pretrained(model_dir,local_files_only=True,trust_remote_code=False)
        model, info=Gemma4ForConditionalGeneration.from_pretrained(model_dir,local_files_only=True,trust_remote_code=False,
            dtype=torch.float32,device_map=None,attn_implementation='eager',experts_implementation='eager',
            use_safetensors=True,ignore_mismatched_sizes=False,output_loading_info=True)
        check_loading(info)
        model=model.to('cpu').eval()
        for p in model.parameters():
            if p.device.type!='cpu' or p.dtype!=torch.float32 or not torch.isfinite(p).all():
                raise RuntimeError('native_parameter_device_dtype_or_finiteness')
        if model.get_input_embeddings().weight.data_ptr()!=model.get_output_embeddings().weight.data_ptr():
            raise RuntimeError('native_tied_embeddings')
        tokenizer=processor.tokenizer
        if tokenizer.bos_token_id!=2 or tokenizer.convert_tokens_to_ids('<|video|>')!=config['video_token_id']:
            raise RuntimeError('native_token_identity')
        fixture=ROOT/'fixtures';fixture.mkdir(exist_ok=True)
        image=Image.new('RGB',(256,256),'white');draw=ImageDraw.Draw(image)
        draw.rectangle((20,30,110,220),fill='red');draw.ellipse((140,70,230,160),fill='blue');image.save(fixture/'image.png')
        frames=[]
        for n in range(4):
            frame=Image.new('RGB',(256,256),'white');ImageDraw.Draw(frame).rectangle((16+48*n,80,64+48*n,176),fill='red')
            frame.save(fixture/f'frame-{n}.png');frames.append(np.asarray(frame))
        class FiniteLogits(LogitsProcessor):
            def __call__(self, input_ids, scores):
                # Negative infinity can be a native mask; NaN/+infinity or no finite choice is invalid.
                if torch.isnan(scores).any() or torch.isposinf(scores).any() or not torch.isfinite(scores).any(dim=-1).all():
                    raise RuntimeError('invalid_generation_logits')
                return scores
        def engine(job):
            content=[]; kwargs={}
            if job=='image': content.append({'type':'image'});kwargs['images']=[image]
            if job=='video':
                content.append({'type':'video'})
                kwargs.update(videos=[np.stack(frames)],video_metadata=[VideoMetadata(total_num_frames=4,fps=1.0,width=256,height=256,duration=4.0,video_backend='author-original-array',frames_indices=[0,1,2,3])])
            content.append({'type':'text','text':PROMPTS[job]})
            prompt=processor.apply_chat_template([{'role':'user','content':content}],tokenize=False,add_generation_prompt=True,enable_thinking=False)
            inputs=processor(text=[prompt],add_special_tokens=False,return_tensors='pt',
                images_kwargs={'max_soft_tokens':70},videos_kwargs={'max_soft_tokens':70,'do_sample_frames':False},**kwargs)
            # Keep every native model tensor: text, attention, multimodal type, pixel and position inputs.
            if any(not torch.is_tensor(v) for v in inputs.values()): raise RuntimeError('unexpected_non_tensor_processor_output')
            ids=inputs['input_ids'];n=int(ids.shape[-1])
            if ids.ndim!=2 or ids.shape[0]!=1 or not 1<=n<=3840 or int(ids[0,0])!=2 or int((ids==2).sum())!=1:
                raise RuntimeError('full_expanded_input_budget_or_bos')
            media_id=config['image_token_id'] if job=='image' else config['video_token_id']
            media=int((ids==media_id).sum()) if job!='text' else 0
            if job=='image' and (not 1<=media<=70 or 'pixel_values' not in inputs or list(inputs['pixel_values'].shape)!=[1,630,768] or list(inputs['image_position_ids'].shape)!=[1,630,2]): raise RuntimeError('image_expansion')
            if job=='video' and (not 4<=media<=280 or 'pixel_values_videos' not in inputs or list(inputs['pixel_values_videos'].shape)!=[1,4,630,768] or list(inputs['video_position_ids'].shape)!=[1,4,630,2]): raise RuntimeError('video_expansion')
            for v in inputs.values():
                if v.is_floating_point() and not torch.isfinite(v).all(): raise RuntimeError('nonfinite_processor_tensor')
            with torch.inference_mode():
                generated=model.generate(**inputs,max_new_tokens=256,do_sample=False,use_cache=True,
                    eos_token_id=[1,106,50],pad_token_id=0,logits_processor=LogitsProcessorList([FiniteLogits()]))
            suffix=generated[0,n:].tolist()
            if not suffix or len(suffix)>256 or suffix[-1] not in (1,106): raise RuntimeError('length_or_nonfinal_stop')
            text=tokenizer.decode(suffix[:-1],skip_special_tokens=False).strip()
            return validate_result(job,{'job':job,'text':text,'input_tokens':n,'output_tokens':len(suffix),'media_tokens':media,'frames':4 if job=='video' else 0,'stop_id':suffix[-1]})
        return engine
    
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  4. 4. Write private serial transport

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat >> multimodal_server.py <<'PYCODE'
    def create_server(engine, key, port=PORT):
        if not isinstance(key, str) or len(key) != 64 or any(c not in '0123456789abcdef' for c in key):
            raise ValueError('key_format')
    
        class Handler(BaseHTTPRequestHandler):
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
    
            def log_message(self, *_):
                pass  # Do not log Bearer keys or request bodies.
    
            def reply(self, status, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(status)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                self.wfile.write(data)
                self.close_connection = True
    
            def authorized(self):
                values = self.headers.get_all('Authorization', [])
                return len(values) == 1 and hmac.compare_digest(values[0].encode(), ('Bearer ' + key).encode())
    
            def do_GET(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/health':
                    return self.reply(404, {'error': 'not_found'})
                return self.reply(200, {'ready': True, 'model': 'google/gemma-4-26B-A4B-it', 'jobs': ['text','image','video'], 'context_limit': 4096, 'max_new_tokens':256})
    
            def do_POST(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/v1/fixed-multimodal':
                    return self.reply(404, {'error': 'not_found'})
                if self.headers.get('Transfer-Encoding') is not None:
                    return self.reply(400, {'error': 'transfer_encoding_unsupported'})
                lengths = self.headers.get_all('Content-Length', [])
                if len(lengths) != 1:
                    return self.reply(411, {'error': 'content_length_required'})
                raw = lengths[0]
                if not raw or len(raw) > 4 or any(c not in '0123456789' for c in raw):
                    return self.reply(413, {'error': 'invalid_or_excessive_length'})
                n = int(raw)
                if n < 1 or n > 256:
                    return self.reply(413, {'error': 'body_limit'})
                if self.headers.get_content_type() != 'application/json':
                    return self.reply(415, {'error': 'json_required'})
                try:
                    body = self.rfile.read(n)
                except (TimeoutError, OSError):
                    return self.reply(408, {'error': 'body_timeout'})
                if len(body) != n:
                    return self.reply(400, {'error': 'incomplete_body'})
                try:
                    def unique(pairs):
                        obj = {}
                        for k, v in pairs:
                            if k in obj:
                                raise ValueError('duplicate_key')
                            obj[k] = v
                        return obj
                    request = json.loads(body.decode('utf-8'), object_pairs_hook=unique,
                                         parse_constant=lambda _: (_ for _ in ()).throw(ValueError('constant')))
                except (ValueError, UnicodeError, RecursionError):
                    return self.reply(400, {'error': 'invalid_json'})
                if type(request) is not dict or set(request) != {'job'} or type(request['job']) is not str or request['job'] not in ('text','image','video'):
                    return self.reply(400, {'error': 'fixed_job_required'})
                try:
                    result = validate_result(request['job'], engine(request['job']))
                except Exception:
                    return self.reply(500, {'error': 'native_generation_or_validation_failure'})
                return self.reply(200, result)
    
        return HTTPServer(('127.0.0.1', port), Handler)
    
    
    if __name__ == '__main__':
        secret=(ROOT/'.api-key').read_text().strip()
        engine=make_engine()
        with create_server(engine,secret) as server:
            server.serve_forever()
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  5. 5. Check the complete wrapper bytes

    Compile syntax without executing imports or loading the model, and compare the exact whole wrapper digest.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    .venv/bin/python -m py_compile multimodal_server.py
    sha256sum --check <<'SHA256'
    09e217ebbeb8cb5892c755f4fe22437cf7616f8b5b021f8e4c40c0c34d7a16aa  multimodal_server.py
    SHA256

    Expected result: Python syntax and exact whole-wrapper SHA-256 pass.

Start the model

  1. 1. Start the complete native multimodal model

    The reader loads both complete shards with no remote code and explicit eager attention/experts, CPU FP32 and eval mode. All load diagnostics must be empty; conversion errors are fatal in the released loader. Parameter CPU/dtype/finiteness and native tied embeddings are checked. Startup and parameter scans can be slow; no inference deadline or fit is promised.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    export HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1
    .venv/bin/python multimodal_server.py

    Expected result: Only after actual native initialization succeeds does the serial service listen on loopback 127.0.0.1:9006. Failure stops startup; do not ignore or suppress missing keys.

Connect to your endpoint

http://127.0.0.1:9006/v1/fixed-multimodal

This trusted workstation loopback only. All shown checks run on the same machine; no remote access is configured.

Access: loopback. Use the stable private Bearer key for health and generation. Send one JSON object with job set to text, image or video. The response includes text, exact native input and output token counts, media positions, frame count and final stop ID. Arbitrary prompts, uploads, URLs, files, tools and audio are rejected. This is a reader-authored fixed-schema endpoint, not an OpenAI-compatible or publisher production service.

Verify the setup

  1. 1. Run all three bounded native checks

    From a second server terminal, authenticate health and request each fixed job. Inspect the original image and all four frames locally. The text answer should be checked against eight hours; inspect shape/color fidelity and whether the rectangle moves right through the authored sequence. These are human checks, not promised outputs, accuracy or real-video performance. Every full expanded input is bounded to 3840 and the response to 256 tokens; length caps, tool handoff and unexpected thought/control tokens fail.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    GEMMA_KEY="$(cat .api-key)"
    curl --fail http://127.0.0.1:9006/health -H "Authorization: Bearer $GEMMA_KEY"
    for JOB in text image video; do
     curl --fail http://127.0.0.1:9006/v1/fixed-multimodal -H "Authorization: Bearer $GEMMA_KEY" -H 'Content-Type: application/json' -d "{\"job\":\"$JOB\"}" -o "$JOB-result.json"
    done
    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9006/health
    unset GEMMA_KEY
    .venv/bin/python - <<'PYVERIFY'
    import json
    from multimodal_server import validate_result
    for job in ('text','image','video'):
     d=validate_result(job,json.load(open(job+'-result.json')))
     print(job,d)
    print('Inspect fixtures/image.png and frame-0.png through frame-3.png. Record grounded correctness, errors and ordering without a quality guarantee.')
    PYVERIFY

    Expected result: Authorized health and three strict response objects succeed only after actual reader execution; missing authorization returns 401. Record native input/output/media counts and manual findings, including failures.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • Full native Gemma 4 26B-A4B includes complete routed language experts and integrated vision. Active A4B naming is not whole-model storage or memory. Serialized weights, API BF16 scalar count and index parameter metadata are separately reported; no fit or throughput is measured.
  • The native text configuration advertises 262144 positions. This deliberate 4096-position recipe bounds actual full processor-expanded inputs to 3840 plus up to 256 generated tokens. It does not claim full native context support, fit, speed or quality.
  • Image budgets of 70, 140, 280, 560 and 1120 are native supported choices. This recipe selects at most 70 soft positions for one image or each of four video frames. Actual expansion, wrappers, timestamps and text are counted in the full native input IDs; nominal visual budgets are not a global text limit.
  • Video uses the full native video processor with an in-memory four-frame RGB sequence, do_sample_frames=False and explicit one-frame-per-second metadata. Authored timestamps 0 through 3 seconds describe this synthetic sequence. No codec, real recording, media download or 60-second card-limit performance is claimed.
  • Publisher processor defaults of 32 frames and model-card video guidance up to 60 seconds at one frame per second are distinct from this bounded four-frame configuration. Broader real-video sampling, uploads, streaming and long-context workflows remain open.
  • Native enable_thinking=False selects the empty thought prefix; generated thought/tool/control tokens and non-final stop ID 50 are rejected. Greedy decoding is an explicit author choice, not a transfer of another model sampler or a guarantee of no unexpected output.
  • The selected native model has audio_config null although its generic processor file contains audio feature-extractor metadata. No audio model or audio workflow is claimed. Text, image and temporal video remain fully integrated in this pair.
  • The runtime uses the released native eager attention and MoE experts on CPU with complete FP32 parameters. GPU/custom-kernel/quantized, remote-code, smaller-model and component-deletion shortcuts are absent. Unexecuted source support does not prove successful loading, peak memory or numerical quality.
  • All ten native files are verified before model import. The full local-only model loader rejects missing, unexpected, mismatched and error diagnostics; released loader conversion errors are fatal. Stop on any mismatch rather than allowing random or incomplete tensors.
  • The private serial HTTPServer has bounded body/framing/authentication and fixed jobs, but no native inference timeout, TLS, multiuser resilience or production security guarantee. It is educational and must remain on trusted loopback.
  • 256 GiB RAM, 400 GiB disk and 16 threads are planning allocations on the exact reused hardware references. FP32 parameter storage alone is about 103.2 GB from API metadata; native loading copies, attention, cache, buffers, environment and OS require unknown additional memory.
  • Exact CPU wheel digests and direct dependency releases are pinned; transitive and system dependencies resolve at reader install, must pass pip check and must be recorded. No installation, model import, tokenizer/BPE, media preprocessing or inference was executed by this author; fake tests cover protocol boundaries only.
  • This ordinary frozen canonical is a documented exact native checkpoint choice, not provider serving byte equivalence. The separate free canonical is not merged or automatically duplicated. Family/backend/modality job totals remain null and open; this pair is not final coverage.
Hash, load diagnostic, dtype or tied-weight failure
Stop and restore the exact complete native snapshot and CPU environment. Do not delete shards, ignore loading mismatches, enable remote code or substitute another Gemma model.
Expanded input, media count or frame metadata failure
Use only the exact original fixtures and four-frame metadata. Keep do_sample_frames=False and native max_soft_tokens=70. Do not truncate the prompt or drop vision tensors to bypass the full native budget.
Non-final stop, length cap, unexpected thought or incorrect answer
Record the failure honestly. The configured greedy non-thinking mode is bounded and source-qualified, not a correctness guarantee. Do not silently strip thought/tools or call a capped response complete.
401, body or request rejection
Use the stable private key and exact single job field. No custom prompts, media paths, URLs or uploads are accepted.
Native CPU memory or dependency failure
Stop and save the exact error and installed-requirements.txt. Allocation and source-only fake tests do not prove fit. Preserve full model/modalities; a different supported allocation or backend needs separate qualification.

Stop the model

  1. 1. Stop the private service

    Use Ctrl-C in the server terminal.

    Command
    set -e
    curl -s -o /dev/null -w '%{http_code}\n' --max-time 3 http://127.0.0.1:9006/health || true

    Expected result: After Ctrl-C the private listener no longer responds. No model service remains running.

Uninstall

  1. 1. Remove the dedicated reader workspace

    Delete only this explicitly named workspace after preserving desired reader results.

    Command
    set -e
    rm -rf -- "$HOME/gemma4-26b-native"

    Expected result: The dedicated environment, complete model files, original fixtures, results and private key are removed. Shared system packages remain.

Sources and verification

Sources checked Oct 17, 2026. Verification source

Compare this configuration
Cloud serverDocumented setupSources checked Oct 17, 2026

Run complete native Gemma 4 26B-A4B text, image and video checks on a private CPU VM

Load the complete publisher-native Gemma 4 26B-A4B instruction checkpoint in CPU FP32 using the released Transformers runtime. A private serial harness runs a grounded text question, an original RGB geometry image and a four-frame moving-object video through the native template and processors. Every expanded input is bounded to 3,840 tokens with up to 256 new tokens inside a 4,096-token configured sequence. The 256 GiB RAM and 400 GiB disk allocation is unmeasured; no fit, speed or model-quality result is claimed.

Hardware
AWS r7i.8xlarge CPU,256GiB RAM,400GiB gp3,16 allocated threads
Runtime
Native Gemma 4 full multimodal CPU Transformers 5.11.0; Torch 2.11.0 CPU; torchvision 0.26.0 CPU; Python 3.12 · CPU
Model format
Safetensors · All complete native floating parameters loaded as CPU FP32; publisher stored dtype BF16 · Unquantized publisher BF16 checkpoint; reader explicitly loads all floating model parameters as CPU FP32
Workload
4,096 token context · 1 concurrent

Based on source documentation; this setup has not been executed by OpenTools. Memory: unknown. No compatible measurement available.

Read the complete setup guide

Before you start

  • Use an existing authorized AWS r7i.8xlarge in us-east-1 with Ubuntu 24.04 x86_64, 256 GiB RAM, 400 GiB gp3 disk and 16 allocated CPU threads. Retain existing SSH access; close service port 9006.
  • Python 3.12 and the exact CPU Torch 2.11.0 / torchvision 0.26.0 wheels are selected for this released Transformers 5.11.0 route. No CUDA, Flash Attention, grouped-matrix custom kernels, media codec, audio dependency or remote code is required for the explicit native eager path. Save the resolved environment and stop on pip check or import failures.
  • Review the exact native Apache 2 model grant and publisher responsible-use guidance. Use the complete Google snapshot; do not substitute a smaller, Diffusion, GGUF or text-only model. No model operations, rights acceptance or suitability review was performed by the author.
  • Only three fixed jobs are accepted: a short grounded text question, an original geometry image and four original RGB frames with explicit one-frame-per-second authored timing. These are controlled reader-generated inputs, not third-party media, recorded video, benchmark evidence or a quality guarantee.
  • The frozen ordinary catalog canonical is mapped to this explicit native checkpoint as a documented deployment choice, not byte equivalence to provider serving. The separate :free canonical remains identity-qualified separately; this pair does not assert free endpoint availability or merge canonicals.

Exact model and requirements

Artifact:
Google / Gemma 4 26B-A4B instruction-tuned complete native multimodal checkpoint · checkpoint google/gemma-4-26B-A4B-it
Publisher revision:
4d7ae4984b7db7de8f8457170b3f1a419ee76d52
Artifact digest:
Two separately hashed native shards form the complete weights; no invented composition digest.
Download size:
48.07 GiB
Memory requirement (unknown):
Unknown — Full CPU FP32 load, attention/cache, image/video tensors, buffers and process peak are unmeasured.
System RAM / disk:
Unknown / Unknown
Placement:
single device. Two complete on-disk Safetensors parts load one native model on one CPU host; no tensor or pipeline sharding. One CPU host, full integrated language and vision model; no accelerator, device map, quantization or component offload.
KV cache:
Native FP32 eager attention cache follows the explicitly FP32 CPU model. Thirty layers mix five sliding-window attention layers with one global-attention layer per six-layer group; local/global head layouts differ. Exact cache/process peak is unmeasured.
Workload:
4,096 token context; Unknown; Unknown; concurrency 1; batch 1; cache cold; repetitions Unknown.
Tokenizer:
Exact native Gemma tokenizer, full standalone Jinja and native image/video processors · 4d7ae4984b7db7de8f8457170b3f1a419ee76d52
Sampling / reasoning:
Author-selected deterministic greedy decoding, do_sample=False, max_new_tokens=256, batch/concurrency 1. Native sampling defaults are temperature 1.0, top-k 64 and top-p 0.95; they are inactive under this explicit greedy override. Native final EOS IDs 1 and 106 are required; tool handoff ID 50 stops generation but is rejected as a non-final result. Native enable_thinking=False renders the publisher empty thought-channel prefix. Unexpected thought/tool/control output is rejected instead of silently stripped. Native autoregressive full-model text, image and video handling is retained; no Diffusion or text-only substitution, tools, audio or agent execution.
Runtime prerequisites:
Ubuntu 24.04 x86_64; See prerequisites above.

Official artifact · License

The exact native Google model card declares Apache License 2.0 and links to the archived actual Apache 2 grant. Preserve the license, copyright, attribution and NOTICE obligations, identify modifications and observe patent/termination and warranty conditions. This exact full Gemma 4 checkpoint is not Gemma Diffusion or a prior restricted Gemma release; no terms acceptance or legal clearance is performed here. Publisher safety and responsible-use guidance still matters; this controlled demonstrator does not establish safety or suitability.

  • Complete serialized native weights total 51,612,009,916 bytes across both shards. API BF16 scalar metadata counts 25,805,936,206 elements, which would occupy 103,223,744,824 bytes if all FP32; this is a parameter-storage calculation, not resident-memory or peak fit proof.
  • Index metadata separately reports total_parameters 26,544,131,376 and total_size 51,611,872,412. Those fields differ from API dtype scalar counts and serialized bytes; none is silently substituted for measured RAM.
  • 256 GiB system RAM, 400 GiB free disk and 16 runtime threads are selected planning allocations. Loading, the complete vision tower, hybrid sliding/global cache, 4K inputs, dependency environment and OS add unknown overhead. No active-parameter shortcut or sibling fit/speed transfer.

One-time setup and hardware

hardware
Not applicable — AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable.
AWS hardware acquisition is included in compute rental; no purchased GPU required. Any separate hardware cost is not applicable. Tax: unknown.
setup
Unknown — Initial provisioning/build time and labor cost are unknown.
Initial provisioning/build time and labor cost are unknown. Tax: unknown.

Recurring costs

compute
$2.12 / hour
Exact AWS published us-east-1 Linux On-Demand row: USD2.1168 per billed instance-hour. Eight hours USD16.9344;24 hours USD50.8032 compute. Idle running hours bill. Storage, transfer, taxes and administration are separate; capacity unknown. Region: us-east-1. SKU: r7i.8xlarge Linux On-Demand. Tax: excluded. Price dated Oct 15, 2026. Price source
storage
$0.08 / GB month
Existing dated us-east-1 gp3 quote USD0.08 per GB-month, with GB defined as1024^3 bytes. Selected400GiB costs USD32 per full month, prorated by provisioned duration, at baseline3000IOPS/125MB/s. Retained resources and snapshots bill separately. Region: us-east-1. SKU: EBS gp3 baseline 3000 IOPS / 125 MB/s. Tax: excluded. Price dated Oct 16, 2026. Price source
egress
Unknown — Data transfer price, allowances and traffic volume are unknown.
Data transfer price, allowances and traffic volume are unknown. Tax: unknown.
administration
Unknown — Maintenance labor rate and hours are unknown.
Maintenance labor rate and hours are unknown. Tax: unknown.

Install the runtime

  1. 1. Install the source-qualified CPU environment

    Install only in a dedicated virtual environment. Wheel URL hashes pin both CPU artifacts without changing the publisher model. Other explicit direct pins satisfy the archived released dependency constraints; transitive and system packages resolve at reader install and must be recorded. No installation was executed by this author.

    Command
    set -e
    sudo apt-get update
    sudo apt-get install -y python3.12 python3.12-venv curl ca-certificates openssl
    mkdir -p "$HOME/gemma4-26b-native"
    cd "$HOME/gemma4-26b-native"
    python3.12 -m venv .venv
    .venv/bin/python -m pip install 'https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl#sha256=f82e2ae20c1545bb03997d1cc3143d94e14b800038669ee1aca45808a9acc338' 'https://download-r2.pytorch.org/whl/cpu/torchvision-0.26.0%2Bcpu-cp312-cp312-manylinux_2_28_x86_64.whl#sha256=cf547dc0975eb40bc3249be4ccbeb736597d2c3ece305b1c4e5b7a5dd7363567'
    .venv/bin/python -m pip install transformers==5.11.0 huggingface-hub==1.5.0 tokenizers==0.22.2 regex==2025.10.22 numpy==2.2.3 Pillow==11.1.0 safetensors==0.5.3
    .venv/bin/python -m pip check
    .venv/bin/python -m pip freeze > installed-requirements.txt

    Expected result: The CPU wheels, exact direct versions and dependency consistency checks succeed; preserve the resolved lock output and stop on failure.

Download the model

  1. 1. Write the exact complete native manifest

    All ten runtime/card/config/tokenizer/weight files are retained. Both weight bodies and tokenizer are downloaded only by the reader. SHA-256 LFS content hashes and native Git blob identities are distinct and explicitly verified; no unqualified mutable main downloads.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat > artifact-manifest.json <<'MANIFEST'
    {
      "repo": "google/gemma-4-26B-A4B-it",
      "revision": "4d7ae4984b7db7de8f8457170b3f1a419ee76d52",
      "files": [
        {
          "path": "README.md",
          "bytes": 27979,
          "algorithm": "git-sha1",
          "digest": "742346e1fe57997c831b9065f4c54a9416021526"
        },
        {
          "path": "chat_template.jinja",
          "bytes": 18683,
          "algorithm": "git-sha1",
          "digest": "4741bf6e4132ba23a5537f9d6e74e9a6d613d7cd"
        },
        {
          "path": "config.json",
          "bytes": 3815,
          "algorithm": "git-sha1",
          "digest": "f42adcca257bb0865c506947671e7d0af52ac9c4"
        },
        {
          "path": "generation_config.json",
          "bytes": 208,
          "algorithm": "git-sha1",
          "digest": "e605bb4523b1462ea9d9a3810b9e3ecf7ab7b1f6"
        },
        {
          "path": "model-00001-of-00002.safetensors",
          "bytes": 49907246508,
          "algorithm": "sha256",
          "digest": "1127684971bbca40465435a5cad69d67ad603bf5e61c6dfd5561fae4a3bcfdb3"
        },
        {
          "path": "model-00002-of-00002.safetensors",
          "bytes": 1704763408,
          "algorithm": "sha256",
          "digest": "aab47033e1e8a492ef8e581efae1cf36478d0433567e7729b3c1728bc8970db7"
        },
        {
          "path": "model.safetensors.index.json",
          "bytes": 103196,
          "algorithm": "git-sha1",
          "digest": "889ab10e12aca96c43c9804a041fb1780de1e5ca"
        },
        {
          "path": "processor_config.json",
          "bytes": 1689,
          "algorithm": "git-sha1",
          "digest": "5465974d23e1eca2c46c2809b26c997946ce0d90"
        },
        {
          "path": "tokenizer.json",
          "bytes": 32169626,
          "algorithm": "sha256",
          "digest": "cc8d3a0ce36466ccc1278bf987df5f71db1719b9ca6b4118264f45cb627bfe0f"
        },
        {
          "path": "tokenizer_config.json",
          "bytes": 3082,
          "algorithm": "git-sha1",
          "digest": "6068e357379d36f823c377e30efb101fa2c67fe4"
        }
      ]
    }
    MANIFEST
    cat > reader-download.py <<'PYDOWNLOAD'
    import hashlib,json,pathlib,urllib.request
    root=pathlib.Path('model');root.mkdir(exist_ok=True)
    manifest=json.load(open('artifact-manifest.json'))
    base='https://huggingface.co/'+manifest['repo']+'/resolve/'+manifest['revision']+'/'
    for row in manifest['files']:
     path=root/row['path'];path.parent.mkdir(parents=True,exist_ok=True)
     if not path.exists():
      temporary=path.with_name(path.name+'.partial')
      with urllib.request.urlopen(base+row['path'],timeout=120) as src,temporary.open('wb') as dst:
       for chunk in iter(lambda:src.read(1024*1024),b''):dst.write(chunk)
      temporary.replace(path)
     if path.stat().st_size!=row['bytes']:raise SystemExit('wrong size: '+row['path'])
     digest=hashlib.sha256() if row['algorithm']=='sha256' else hashlib.sha1()
     if row['algorithm']=='git-sha1':digest.update(b'blob '+str(row['bytes']).encode()+b'\0')
     with path.open('rb')as src:
      for chunk in iter(lambda:src.read(1024*1024),b''):digest.update(chunk)
     if digest.hexdigest()!=row['digest']:raise SystemExit('wrong digest: '+row['path'])
    index=json.load(open(root/'model.safetensors.index.json'))
    assert set(index['weight_map'].values())=={'model-00001-of-00002.safetensors','model-00002-of-00002.safetensors'}
    assert sum(x['bytes']for x in manifest['files']if x['path'].endswith('.safetensors'))==51612009916
    print('All ten pinned native files verified; two complete model shards retained.')
    PYDOWNLOAD
    .venv/bin/python reader-download.py

    Expected result: All ten files match their exact pinned sizes and SHA-256 or Git blob identity; the complete two-shard index set is checked before any model import. Stop on mismatch.

Configure

  1. 1. Create a stable private key

    Create the reader-generated secret only when absent, keep it private and refuse an empty existing file. No key is generated or executed by the author.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    umask 077
    if [ ! -e .api-key ]; then openssl rand -hex 32 > .api-key; fi
    test -s .api-key
    chmod 600 .api-key

    Expected result: A stable private 64-character hexadecimal key exists with restricted permissions; later reader startup checks its exact format.

  2. 2. Write strict output guards

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat > multimodal_server.py <<'PYCODE'
    """Reader-authored private Gemma4 full-native educational harness; not publisher server."""
    import hashlib
    import hmac
    import json
    import math
    import pathlib
    from http.server import BaseHTTPRequestHandler, HTTPServer
    ROOT = pathlib.Path(__file__).resolve().parent
    PORT = 9006
    PIN = '4d7ae4984b7db7de8f8457170b3f1a419ee76d52'
    PROMPTS = {'text':'The library opens at 09:00 and closes at 17:00 on the same day. How many hours is it open? Answer briefly.',
    'image':'Describe the visible colors and shapes in this original geometry image. Answer briefly.',
    'video':'Describe how the red rectangle changes position from the first frame to the last. Answer briefly; do not invent events outside the frames.'}
    
    def validate_result(job, d):
        if type(d) is not dict or set(d) != {'job','text','input_tokens','output_tokens','media_tokens','frames','stop_id'}:
            raise ValueError('result_schema')
        if d['job'] != job or type(d['text']) is not str or not d['text'].strip() or len(d['text'])>16384:
            raise ValueError('result_text')
        for k in ('input_tokens','output_tokens','media_tokens','frames','stop_id'):
            if type(d[k]) is not int:
                raise ValueError('result_integer')
        if not 1<=d['input_tokens']<=3840 or not 1<=d['output_tokens']<=256 or d['input_tokens']+d['output_tokens']>4096:
            raise ValueError('result_context')
        if d['stop_id'] not in (1,106) or d['frames'] != (4 if job=='video' else 0):
            raise ValueError('result_stop_or_frames')
        if (job=='text' and d['media_tokens']!=0) or (job=='image' and not 1<=d['media_tokens']<=70) or (job=='video' and not 4<=d['media_tokens']<=280):
            raise ValueError('result_media')
        if any(s in d['text'] for s in ('<|','|>','<channel|>','<tool_call|>','<tool_response|>','<turn|>','<eos>','<bos>')):
            raise ValueError('unexpected_native_control')
        return d
    
    def check_loading(info):
        expected={'missing_keys','unexpected_keys','mismatched_keys','error_msgs'}
        if type(info) is not dict or set(info)!=expected or any(info[k] for k in expected):
            raise RuntimeError('incomplete_or_incompatible_checkpoint')
    
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  3. 3. Write full native CPU adapter

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat >> multimodal_server.py <<'PYCODE'
    def make_engine():
        # Only the reader invokes this path. Fake protocol tests never import native libraries.
        model_dir=ROOT/'model'
        manifest=json.loads((ROOT/'artifact-manifest.json').read_text())
        for row in manifest['files']:
            path=model_dir/row['path']
            if path.stat().st_size!=row['bytes']: raise RuntimeError('artifact_size')
            digest=hashlib.sha256() if row['algorithm']=='sha256' else hashlib.sha1()
            if row['algorithm']=='git-sha1': digest.update(b'blob '+str(row['bytes']).encode()+b'\0')
            with path.open('rb') as handle:
                for chunk in iter(lambda:handle.read(1024*1024),b''): digest.update(chunk)
            actual=digest.hexdigest()
            if actual!=row['digest']: raise RuntimeError('artifact_hash')
        config=json.loads((model_dir/'config.json').read_text())
        if config['architectures']!=['Gemma4ForConditionalGeneration'] or config.get('audio_config') is not None:
            raise RuntimeError('wrong_native_architecture')
        import numpy as np
        import torch
        from PIL import Image, ImageDraw
        from transformers import AutoProcessor, Gemma4ForConditionalGeneration, LogitsProcessor, LogitsProcessorList
        from transformers.video_utils import VideoMetadata
        torch.set_num_threads(16)
        processor=AutoProcessor.from_pretrained(model_dir,local_files_only=True,trust_remote_code=False)
        model, info=Gemma4ForConditionalGeneration.from_pretrained(model_dir,local_files_only=True,trust_remote_code=False,
            dtype=torch.float32,device_map=None,attn_implementation='eager',experts_implementation='eager',
            use_safetensors=True,ignore_mismatched_sizes=False,output_loading_info=True)
        check_loading(info)
        model=model.to('cpu').eval()
        for p in model.parameters():
            if p.device.type!='cpu' or p.dtype!=torch.float32 or not torch.isfinite(p).all():
                raise RuntimeError('native_parameter_device_dtype_or_finiteness')
        if model.get_input_embeddings().weight.data_ptr()!=model.get_output_embeddings().weight.data_ptr():
            raise RuntimeError('native_tied_embeddings')
        tokenizer=processor.tokenizer
        if tokenizer.bos_token_id!=2 or tokenizer.convert_tokens_to_ids('<|video|>')!=config['video_token_id']:
            raise RuntimeError('native_token_identity')
        fixture=ROOT/'fixtures';fixture.mkdir(exist_ok=True)
        image=Image.new('RGB',(256,256),'white');draw=ImageDraw.Draw(image)
        draw.rectangle((20,30,110,220),fill='red');draw.ellipse((140,70,230,160),fill='blue');image.save(fixture/'image.png')
        frames=[]
        for n in range(4):
            frame=Image.new('RGB',(256,256),'white');ImageDraw.Draw(frame).rectangle((16+48*n,80,64+48*n,176),fill='red')
            frame.save(fixture/f'frame-{n}.png');frames.append(np.asarray(frame))
        class FiniteLogits(LogitsProcessor):
            def __call__(self, input_ids, scores):
                # Negative infinity can be a native mask; NaN/+infinity or no finite choice is invalid.
                if torch.isnan(scores).any() or torch.isposinf(scores).any() or not torch.isfinite(scores).any(dim=-1).all():
                    raise RuntimeError('invalid_generation_logits')
                return scores
        def engine(job):
            content=[]; kwargs={}
            if job=='image': content.append({'type':'image'});kwargs['images']=[image]
            if job=='video':
                content.append({'type':'video'})
                kwargs.update(videos=[np.stack(frames)],video_metadata=[VideoMetadata(total_num_frames=4,fps=1.0,width=256,height=256,duration=4.0,video_backend='author-original-array',frames_indices=[0,1,2,3])])
            content.append({'type':'text','text':PROMPTS[job]})
            prompt=processor.apply_chat_template([{'role':'user','content':content}],tokenize=False,add_generation_prompt=True,enable_thinking=False)
            inputs=processor(text=[prompt],add_special_tokens=False,return_tensors='pt',
                images_kwargs={'max_soft_tokens':70},videos_kwargs={'max_soft_tokens':70,'do_sample_frames':False},**kwargs)
            # Keep every native model tensor: text, attention, multimodal type, pixel and position inputs.
            if any(not torch.is_tensor(v) for v in inputs.values()): raise RuntimeError('unexpected_non_tensor_processor_output')
            ids=inputs['input_ids'];n=int(ids.shape[-1])
            if ids.ndim!=2 or ids.shape[0]!=1 or not 1<=n<=3840 or int(ids[0,0])!=2 or int((ids==2).sum())!=1:
                raise RuntimeError('full_expanded_input_budget_or_bos')
            media_id=config['image_token_id'] if job=='image' else config['video_token_id']
            media=int((ids==media_id).sum()) if job!='text' else 0
            if job=='image' and (not 1<=media<=70 or 'pixel_values' not in inputs or list(inputs['pixel_values'].shape)!=[1,630,768] or list(inputs['image_position_ids'].shape)!=[1,630,2]): raise RuntimeError('image_expansion')
            if job=='video' and (not 4<=media<=280 or 'pixel_values_videos' not in inputs or list(inputs['pixel_values_videos'].shape)!=[1,4,630,768] or list(inputs['video_position_ids'].shape)!=[1,4,630,2]): raise RuntimeError('video_expansion')
            for v in inputs.values():
                if v.is_floating_point() and not torch.isfinite(v).all(): raise RuntimeError('nonfinite_processor_tensor')
            with torch.inference_mode():
                generated=model.generate(**inputs,max_new_tokens=256,do_sample=False,use_cache=True,
                    eos_token_id=[1,106,50],pad_token_id=0,logits_processor=LogitsProcessorList([FiniteLogits()]))
            suffix=generated[0,n:].tolist()
            if not suffix or len(suffix)>256 or suffix[-1] not in (1,106): raise RuntimeError('length_or_nonfinal_stop')
            text=tokenizer.decode(suffix[:-1],skip_special_tokens=False).strip()
            return validate_result(job,{'job':job,'text':text,'input_tokens':n,'output_tokens':len(suffix),'media_tokens':media,'frames':4 if job=='video' else 0,'stop_id':suffix[-1]})
        return engine
    
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  4. 4. Write private serial transport

    Reader-authored educational code, not publisher server code. The adapter uses native local-only Transformers loading and processors, checks every complete artifact and load diagnostic, keeps all native model input tensors and rejects malformed or non-final output. No architecture patch or native code import occurs while writing it.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    cat >> multimodal_server.py <<'PYCODE'
    def create_server(engine, key, port=PORT):
        if not isinstance(key, str) or len(key) != 64 or any(c not in '0123456789abcdef' for c in key):
            raise ValueError('key_format')
    
        class Handler(BaseHTTPRequestHandler):
            def setup(self):
                super().setup()
                self.connection.settimeout(5)
    
            def log_message(self, *_):
                pass  # Do not log Bearer keys or request bodies.
    
            def reply(self, status, obj):
                data = json.dumps(obj, allow_nan=False, separators=(',', ':')).encode()
                self.send_response(status)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Content-Length', str(len(data)))
                self.send_header('Connection', 'close')
                self.end_headers()
                self.wfile.write(data)
                self.close_connection = True
    
            def authorized(self):
                values = self.headers.get_all('Authorization', [])
                return len(values) == 1 and hmac.compare_digest(values[0].encode(), ('Bearer ' + key).encode())
    
            def do_GET(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/health':
                    return self.reply(404, {'error': 'not_found'})
                return self.reply(200, {'ready': True, 'model': 'google/gemma-4-26B-A4B-it', 'jobs': ['text','image','video'], 'context_limit': 4096, 'max_new_tokens':256})
    
            def do_POST(self):
                if not self.authorized():
                    return self.reply(401, {'error': 'unauthorized'})
                if self.path != '/v1/fixed-multimodal':
                    return self.reply(404, {'error': 'not_found'})
                if self.headers.get('Transfer-Encoding') is not None:
                    return self.reply(400, {'error': 'transfer_encoding_unsupported'})
                lengths = self.headers.get_all('Content-Length', [])
                if len(lengths) != 1:
                    return self.reply(411, {'error': 'content_length_required'})
                raw = lengths[0]
                if not raw or len(raw) > 4 or any(c not in '0123456789' for c in raw):
                    return self.reply(413, {'error': 'invalid_or_excessive_length'})
                n = int(raw)
                if n < 1 or n > 256:
                    return self.reply(413, {'error': 'body_limit'})
                if self.headers.get_content_type() != 'application/json':
                    return self.reply(415, {'error': 'json_required'})
                try:
                    body = self.rfile.read(n)
                except (TimeoutError, OSError):
                    return self.reply(408, {'error': 'body_timeout'})
                if len(body) != n:
                    return self.reply(400, {'error': 'incomplete_body'})
                try:
                    def unique(pairs):
                        obj = {}
                        for k, v in pairs:
                            if k in obj:
                                raise ValueError('duplicate_key')
                            obj[k] = v
                        return obj
                    request = json.loads(body.decode('utf-8'), object_pairs_hook=unique,
                                         parse_constant=lambda _: (_ for _ in ()).throw(ValueError('constant')))
                except (ValueError, UnicodeError, RecursionError):
                    return self.reply(400, {'error': 'invalid_json'})
                if type(request) is not dict or set(request) != {'job'} or type(request['job']) is not str or request['job'] not in ('text','image','video'):
                    return self.reply(400, {'error': 'fixed_job_required'})
                try:
                    result = validate_result(request['job'], engine(request['job']))
                except Exception:
                    return self.reply(500, {'error': 'native_generation_or_validation_failure'})
                return self.reply(200, result)
    
        return HTTPServer(('127.0.0.1', port), Handler)
    
    
    if __name__ == '__main__':
        secret=(ROOT/'.api-key').read_text().strip()
        engine=make_engine()
        with create_server(engine,secret) as server:
            server.serve_forever()
    PYCODE

    Expected result: The exact source section is written; native libraries and model execution occur only when the reader starts the service.

  5. 5. Check the complete wrapper bytes

    Compile syntax without executing imports or loading the model, and compare the exact whole wrapper digest.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    .venv/bin/python -m py_compile multimodal_server.py
    sha256sum --check <<'SHA256'
    09e217ebbeb8cb5892c755f4fe22437cf7616f8b5b021f8e4c40c0c34d7a16aa  multimodal_server.py
    SHA256

    Expected result: Python syntax and exact whole-wrapper SHA-256 pass.

Start the model

  1. 1. Start the complete native multimodal model

    The reader loads both complete shards with no remote code and explicit eager attention/experts, CPU FP32 and eval mode. All load diagnostics must be empty; conversion errors are fatal in the released loader. Parameter CPU/dtype/finiteness and native tied embeddings are checked. Startup and parameter scans can be slow; no inference deadline or fit is promised.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    export HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1
    .venv/bin/python multimodal_server.py

    Expected result: Only after actual native initialization succeeds does the serial service listen on loopback 127.0.0.1:9006. Failure stops startup; do not ignore or suppress missing keys.

Connect to your endpoint

http://127.0.0.1:9006/v1/fixed-multimodal

VM loopback only. Keep port 9006 closed in the security group. With existing SSH access, run ssh -N -L 9006:127.0.0.1:9006 USER@VM_IP from the trusted client; the shown checks run on the server.

Access: loopback. Use the stable private Bearer key for health and generation. Send one JSON object with job set to text, image or video. The response includes text, exact native input and output token counts, media positions, frame count and final stop ID. Arbitrary prompts, uploads, URLs, files, tools and audio are rejected. This is a reader-authored fixed-schema endpoint, not an OpenAI-compatible or publisher production service.

Verify the setup

  1. 1. Run all three bounded native checks

    From a second server terminal, authenticate health and request each fixed job. Inspect the original image and all four frames locally. The text answer should be checked against eight hours; inspect shape/color fidelity and whether the rectangle moves right through the authored sequence. These are human checks, not promised outputs, accuracy or real-video performance. Every full expanded input is bounded to 3840 and the response to 256 tokens; length caps, tool handoff and unexpected thought/control tokens fail.

    Command
    set -e
    cd "$HOME/gemma4-26b-native"
    GEMMA_KEY="$(cat .api-key)"
    curl --fail http://127.0.0.1:9006/health -H "Authorization: Bearer $GEMMA_KEY"
    for JOB in text image video; do
     curl --fail http://127.0.0.1:9006/v1/fixed-multimodal -H "Authorization: Bearer $GEMMA_KEY" -H 'Content-Type: application/json' -d "{\"job\":\"$JOB\"}" -o "$JOB-result.json"
    done
    curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:9006/health
    unset GEMMA_KEY
    .venv/bin/python - <<'PYVERIFY'
    import json
    from multimodal_server import validate_result
    for job in ('text','image','video'):
     d=validate_result(job,json.load(open(job+'-result.json')))
     print(job,d)
    print('Inspect fixtures/image.png and frame-0.png through frame-3.png. Record grounded correctness, errors and ordering without a quality guarantee.')
    PYVERIFY

    Expected result: Authorized health and three strict response objects succeed only after actual reader execution; missing authorization returns 401. Record native input/output/media counts and manual findings, including failures.

Performance evidence

No compatible measurement available. Documented support and estimated memory do not establish response speed.

Limits and troubleshooting

  • Full native Gemma 4 26B-A4B includes complete routed language experts and integrated vision. Active A4B naming is not whole-model storage or memory. Serialized weights, API BF16 scalar count and index parameter metadata are separately reported; no fit or throughput is measured.
  • The native text configuration advertises 262144 positions. This deliberate 4096-position recipe bounds actual full processor-expanded inputs to 3840 plus up to 256 generated tokens. It does not claim full native context support, fit, speed or quality.
  • Image budgets of 70, 140, 280, 560 and 1120 are native supported choices. This recipe selects at most 70 soft positions for one image or each of four video frames. Actual expansion, wrappers, timestamps and text are counted in the full native input IDs; nominal visual budgets are not a global text limit.
  • Video uses the full native video processor with an in-memory four-frame RGB sequence, do_sample_frames=False and explicit one-frame-per-second metadata. Authored timestamps 0 through 3 seconds describe this synthetic sequence. No codec, real recording, media download or 60-second card-limit performance is claimed.
  • Publisher processor defaults of 32 frames and model-card video guidance up to 60 seconds at one frame per second are distinct from this bounded four-frame configuration. Broader real-video sampling, uploads, streaming and long-context workflows remain open.
  • Native enable_thinking=False selects the empty thought prefix; generated thought/tool/control tokens and non-final stop ID 50 are rejected. Greedy decoding is an explicit author choice, not a transfer of another model sampler or a guarantee of no unexpected output.
  • The selected native model has audio_config null although its generic processor file contains audio feature-extractor metadata. No audio model or audio workflow is claimed. Text, image and temporal video remain fully integrated in this pair.
  • The runtime uses the released native eager attention and MoE experts on CPU with complete FP32 parameters. GPU/custom-kernel/quantized, remote-code, smaller-model and component-deletion shortcuts are absent. Unexecuted source support does not prove successful loading, peak memory or numerical quality.
  • All ten native files are verified before model import. The full local-only model loader rejects missing, unexpected, mismatched and error diagnostics; released loader conversion errors are fatal. Stop on any mismatch rather than allowing random or incomplete tensors.
  • The private serial HTTPServer has bounded body/framing/authentication and fixed jobs, but no native inference timeout, TLS, multiuser resilience or production security guarantee. It is educational and must remain on trusted loopback.
  • 256 GiB RAM, 400 GiB disk and 16 threads are planning allocations on the exact reused hardware references. FP32 parameter storage alone is about 103.2 GB from API metadata; native loading copies, attention, cache, buffers, environment and OS require unknown additional memory.
  • Exact CPU wheel digests and direct dependency releases are pinned; transitive and system dependencies resolve at reader install, must pass pip check and must be recorded. No installation, model import, tokenizer/BPE, media preprocessing or inference was executed by this author; fake tests cover protocol boundaries only.
  • This ordinary frozen canonical is a documented exact native checkpoint choice, not provider serving byte equivalence. The separate free canonical is not merged or automatically duplicated. Family/backend/modality job totals remain null and open; this pair is not final coverage.
Hash, load diagnostic, dtype or tied-weight failure
Stop and restore the exact complete native snapshot and CPU environment. Do not delete shards, ignore loading mismatches, enable remote code or substitute another Gemma model.
Expanded input, media count or frame metadata failure
Use only the exact original fixtures and four-frame metadata. Keep do_sample_frames=False and native max_soft_tokens=70. Do not truncate the prompt or drop vision tensors to bypass the full native budget.
Non-final stop, length cap, unexpected thought or incorrect answer
Record the failure honestly. The configured greedy non-thinking mode is bounded and source-qualified, not a correctness guarantee. Do not silently strip thought/tools or call a capped response complete.
401, body or request rejection
Use the stable private key and exact single job field. No custom prompts, media paths, URLs or uploads are accepted.
Native CPU memory or dependency failure
Stop and save the exact error and installed-requirements.txt. Allocation and source-only fake tests do not prove fit. Preserve full model/modalities; a different supported allocation or backend needs separate qualification.

Stop the model

  1. 1. Stop the private service

    Use Ctrl-C in the server terminal. Close any optional SSH tunnel separately.

    Command
    set -e
    curl -s -o /dev/null -w '%{http_code}\n' --max-time 3 http://127.0.0.1:9006/health || true

    Expected result: After Ctrl-C the private listener no longer responds. Stopping the Python process does not stop EC2 billing.

Uninstall

  1. 1. Remove the dedicated reader workspace

    Delete only this explicitly named workspace after preserving desired reader results. Stop or terminate the EC2 instance separately, inspect retained EBS volumes/snapshots and delete unwanted billable resources in the existing AWS console. Verify the terminal state and retained resources; stopping an instance retains EBS charges.

    Command
    set -e
    rm -rf -- "$HOME/gemma4-26b-native"

    Expected result: The dedicated environment, complete model files, original fixtures, results and private key are removed. EC2 and retained storage cleanup must be confirmed independently in the existing console.

Shut down cloud resources

  1. 1. End cloud billing resources

    In EC2 us-east-1, stop for later reuse or terminate this exact VM. Review Delete on termination for its root volume. Delete unwanted detached EBS volumes, snapshots and reserved/Elastic/public IP resources. Stopped VM storage and retained resources may still bill. Check Bills/Cost Explorer later for final usage.

    Expected result: Exact instance is stopped/terminated as intended; no unwanted attached/retained billed resources remain. Instance compute stops only after its lifecycle transition, not when the Python service stops.

Sources and verification

Sources checked Oct 17, 2026. Verification source

Compare this configuration

Benchmarks

Performance scores for Gemma 4 26B A4B across standard benchmarks.

GPQA DiamondArtificial Analysis
79.2%
Terminal-Bench 2.1Artificial Analysis
39%

Pricing

Token pricing for Gemma 4 26B A4B API usage.

Input Tokens

$0.08/M

per million tokens

Output Tokens

$0.35/M

per million tokens

Cache read: $0.0100/M tokens

Google logo
Googleenterprise

Organizing the world's information with AI

14 Tools6 MCP Servers9 ModelsFounded 1998Mountain View, CA
View full profile

Tools by Google

Other AI tools from the same organization.

AI Models by Google

AI models from the same organization.

ModelContext WindowPrice (In / Out per M)
Gemini Omni 1.1 FlashCurrent1.0M$1.50 / $17.50
Gemini 3.7 FlashCurrent1.0M$0.75 / $3.75
Gemini 3.5 Flash-LiteCurrent1.0M$0.30 / $2.50
Gemini 3.6 FlashCurrent1.0M$1.50 / $7.50
DiffusionGemmaCurrent256K-- / --
Gemma 4 26B A4BCurrent262K-- / --

MCP Servers by Google

Connect this tool to AI assistants via the Model Context Protocol.

Related News

Latest coverage and updates.