Skip to content

Commit c6f6eb7

Browse files
probicheauxclaudePawelPeczek-Roboflow
authored andcommitted
Add NVIDIA Cosmos 3 Edge: reasoner (VLM surface) + generative world model (#2675)
* Add NVIDIA Cosmos 3 Edge reasoner (cosmos-3-edge, vlm, HF backend) Adds the reasoner tower of NVIDIA Cosmos 3 Edge as a core model: - inference_models: Cosmos3EdgeReasoner (prompt/prompt_video following the standard VLM contract) + registry entry (cosmos-3-edge, vlm, hugging-face) - serving bridge: InferenceModelsCosmos3ReasonerAdapter registered in ROBOFLOW_MODEL_TYPES (inference_models-only, gated on COSMOS3_ENABLED and USE_INFERENCE_MODELS), served via the existing /infer/lmm route - workflow block: roboflow_core/cosmos3_edge@v1 emitting language_model_output, GPU-gated via get_restrictions() - mocked unit tests for the model class and the block manifest; changelog The generative world-model tower (image-to-video, dynamics, anomaly generation) ships separately. Weight packaging/registration is pending with the Inference Core team. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add Cosmos 3 Edge generator (cosmos-3-edge-world, world-model task) Generative tower of Cosmos 3 Edge, stacked on the reasoner branch: - Cosmos3EdgeWorldModel (cosmos-3-edge-world, world-model, custom backend): generate_video, start_rollout/forward_dynamics with explicit opaque state_dict threading (raises on missing session), inverse_dynamics returning a Cosmos3ActionTrajectory. Policy mode deferred by design. - New WORLD_MODEL_TASK constant. - Runtime seam: packages ship a self-contained runtime module imported via import_class_from_file (moondream2 precedent) - NVIDIA's cosmos stack is not an inference_models dependency. - Mocked unit tests; changelog. Follow-ups: HTTP entities + workflow blocks for frame/action outputs, policy mode, weight packaging with the Inference Core team. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add Cosmos 3 Edge weight-pull tooling and reference generator runtime - development/cosmos3/pull_weights.py: downloads the nvidia/Cosmos3-Edge snapshot once (the towers share MoT weight shards) and materializes the cosmos-3-edge (reasoner) and cosmos-3-edge-world (generator) package layouts via hardlinks. Supports --snapshot-dir reuse, --runtime-module injection for the world package, and --gcs-dest mirroring (gcloud/gsutil) for uploading the same layout to GCS. - development/cosmos3/reference_generator_runtime.py: the self-contained runtime module shipped inside the world package, backed by diffusers' Cosmos3OmniPipeline (image-to-video working; dynamics methods raise until the action-conditioning path is wired). Verified on an L4 with real weights: reasoner prompt() 8.6s/4.9GB VRAM, world generate_video() 13 frames @416x240 in 6.6s/9.4GB peak. Requires transformers and diffusers git-main builds (cosmos3_edge model type / Cosmos3OmniTransformer are newer than current releases). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Ignore cosmos3 test venv and local checkpoints Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Add pinned optional cosmos requirements (git-SHA transformers/diffusers) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Wire forward/inverse dynamics in reference runtime; add real-weights integration tests - Reference runtime now implements forward dynamics (chunked rollout via CosmosActionCondition, conditioning each chunk on the previous chunk's final frame carried in the session dict) and inverse dynamics (action inference from observation video). action_space maps to the pipeline's embodiment domain_name; generation kwargs (seed, num_inference_steps) pass through. - Cosmos3EdgeWorldModel threads action_space/session options through to the runtime; inverse_dynamics now takes a required action_space. - Integration tests (slow, env-gated local package dirs) for reasoner prompt, image-to-video, and two-chunk forward-dynamics session threading. Validated on L4 against NVIDIA's example assets: FD 2x16 UMI chunks -> 34 frames @256p in 6.6s; ID on the AV example reproduces the published Edge output at 0.945 correlation (MAE 0.10, 15 denoise steps). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Fix CI: black/isort formatting, cosmos3 model license listing - black on inference/models/utils.py, isort on core_steps/loader.py - inference/models/cosmos3/LICENSE.txt (OpenMDW-1.1 full text) and README.md license-table row, satisfying the validate-models check Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Align Cosmos3 reasoner with repo VLM conventions Match the patterns used across the maintained VLM implementations (glm_ocr, gemma4, qwen3_5, smolvlm): - flash-attention-2 selection on Ampere+ CUDA with Jetson guard, eager fallback (glm_ocr pattern) - device-aware dtype resolution (bf16 if supported, fp16 on older CUDA, fp32 on CPU) instead of hardcoded bf16 - cast floating-point processor outputs to the model dtype in pre_process_generation; keep integer tensors intact - max_new_tokens=None resolves to the configured default in generate() - quantization_config passthrough in from_pretrained; pad-token fallback to eos in generate(); __call__ alias for prompt() - thinking-aware post-processing (qwen3_5 pattern): the chat template opens the reasoning block in the prompt, so a bare closing </think> appears in output - strip the block by default, or return {thinking, answer} dicts with return_thinking=True Verified on real weights: default prompt() now returns the clean final answer ('blue' for a blue image) with reasoning available on request. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Adjust cosmos to deployment * Make linters happy * Cosmos dependency fix * Adjust tests * Bump version * Bump dependencies of inference * Fix cosmos deps install * Align version of inference-models * Bump dependencies --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Paweł Pęczek <pawel@roboflow.com>
1 parent e640f6f commit c6f6eb7

31 files changed

Lines changed: 1964 additions & 18 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,4 +217,5 @@ inference_testing
217217
*.rrd
218218

219219
openspec*/
220-
opsx/
220+
opsx/
221+
checkpoints/

docker/dockerfiles/Dockerfile.onnx.gpu

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ RUN ln -s /usr/bin/python3 /usr/bin/python
108108
RUN /bin/make create_wheels_for_gpu_notebook
109109
RUN pip3 install --no-cache-dir dist/inference_cli*.whl dist/inference_core*.whl dist/inference_gpu*.whl dist/inference_sdk*.whl "setuptools<=75.5.0"
110110

111+
# Instal Cosmos 3 preview (requires override of transformers, since 21.07.2026 it was not released yet).
112+
COPY requirements/requirements.cosmos.txt .
113+
RUN python3 -m pip install -r requirements.cosmos.txt
114+
111115
WORKDIR /notebooks
112116
COPY examples/notebooks .
113117

inference/core/env.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@
259259

260260
LMM_ENABLED = str2bool(os.getenv("LMM_ENABLED", False))
261261

262+
COSMOS3_ENABLED = str2bool(os.getenv("COSMOS3_ENABLED", True))
263+
262264
QWEN_2_5_ENABLED = str2bool(os.getenv("QWEN_2_5_ENABLED", True))
263265

264266
QWEN_3_ENABLED = str2bool(os.getenv("QWEN_3_ENABLED", True))

inference/core/workflows/core_steps/loader.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@
238238
from inference.core.workflows.core_steps.models.foundation.cog_vlm.v1 import (
239239
CogVLMBlockV1,
240240
)
241+
from inference.core.workflows.core_steps.models.foundation.cosmos3.v1 import (
242+
Cosmos3EdgeBlockV1,
243+
)
241244
from inference.core.workflows.core_steps.models.foundation.depth_estimation.v1 import (
242245
DepthEstimationBlockV1,
243246
)
@@ -1009,6 +1012,7 @@ def load_blocks() -> List[Type[WorkflowBlock]]:
10091012
GoogleGemmaBlockV1,
10101013
GoogleGemmaBlockV2,
10111014
ImageSlicerBlockV2,
1015+
Cosmos3EdgeBlockV1,
10121016
Qwen25VLBlockV1,
10131017
Qwen3VLBlockV1,
10141018
Qwen35VLBlockV1,

inference/core/workflows/core_steps/models/foundation/cosmos3/__init__.py

Whitespace-only changes.
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
from typing import List, Literal, Optional, Type, Union
2+
3+
from pydantic import ConfigDict, Field
4+
5+
from inference.core.entities.requests.inference import LMMInferenceRequest
6+
from inference.core.env import (
7+
COSMOS3_ENABLED,
8+
HOSTED_CORE_MODEL_URL,
9+
LOCAL_INFERENCE_API_URL,
10+
WORKFLOWS_REMOTE_API_TARGET,
11+
)
12+
from inference.core.managers.base import ModelManager
13+
from inference.core.workflows.core_steps.common.entities import StepExecutionMode
14+
from inference.core.workflows.execution_engine.entities.base import (
15+
Batch,
16+
OutputDefinition,
17+
WorkflowImageData,
18+
)
19+
from inference.core.workflows.execution_engine.entities.types import (
20+
IMAGE_KIND,
21+
LANGUAGE_MODEL_OUTPUT_KIND,
22+
ROBOFLOW_MODEL_ID_KIND,
23+
STRING_KIND,
24+
ImageInputField,
25+
Selector,
26+
)
27+
from inference.core.workflows.prototypes.block import (
28+
BlockResult,
29+
Runtime,
30+
RuntimeRestriction,
31+
Severity,
32+
WorkflowBlock,
33+
WorkflowBlockManifest,
34+
)
35+
from inference_sdk import InferenceHTTPClient
36+
37+
DEFAULT_PROMPT = "Describe what's in this image."
38+
DEFAULT_SYSTEM_PROMPT = (
39+
"You are Cosmos, a helpful assistant that understands physical scenes "
40+
"and answers questions about images and videos."
41+
)
42+
43+
44+
class BlockManifest(WorkflowBlockManifest):
45+
model_config = ConfigDict(
46+
json_schema_extra={
47+
"name": "Cosmos 3",
48+
"version": "v1",
49+
"short_description": "Reason about physical scenes with NVIDIA Cosmos 3.",
50+
"long_description": (
51+
"This workflow block runs the NVIDIA Cosmos 3 reasoner — a world model "
52+
"tuned for physical scene understanding—on an image with an optional text "
53+
"prompt, and returns a text answer. The model is well suited to questions "
54+
"about spatial relations, safety, and what will happen next in a scene."
55+
),
56+
"license": "OpenMDW-1.1",
57+
"block_type": "model",
58+
"search_keywords": [
59+
"Cosmos",
60+
"cosmos3",
61+
"NVIDIA",
62+
"world model",
63+
"vision language model",
64+
"VLM",
65+
"robotics",
66+
],
67+
"is_vlm_block": True,
68+
"ui_manifest": {
69+
"section": "model",
70+
"icon": "fal fa-atom",
71+
"blockPriority": 5.5,
72+
},
73+
},
74+
protected_namespaces=(),
75+
)
76+
type: Literal["roboflow_core/cosmos3_edge@v1"]
77+
78+
images: Selector(kind=[IMAGE_KIND]) = ImageInputField
79+
prompt: Optional[Union[Selector(kind=[STRING_KIND]), str]] = Field(
80+
default=None,
81+
description="Optional text prompt to pass to Cosmos 3 Edge. Otherwise a default "
82+
"scene-description prompt is used, which may affect the desired model behavior.",
83+
examples=["Is the walkway free of obstacles?", "$inputs.prompt"],
84+
)
85+
model_version: Union[
86+
Selector(kind=[ROBOFLOW_MODEL_ID_KIND]), Literal["nvidia/cosmos-3-edge"]
87+
] = Field(
88+
default="nvidia/cosmos-3-edge",
89+
description="The Cosmos 3 Edge model to be used for inference.",
90+
examples=["nvidia/cosmos-3-edge"],
91+
)
92+
system_prompt: Optional[Union[Selector(kind=[STRING_KIND]), str]] = Field(
93+
default=None,
94+
description="Optional system prompt to provide additional context to Cosmos 3 Edge.",
95+
examples=["You are a safety inspector.", "$inputs.system_prompt"],
96+
)
97+
98+
@classmethod
99+
def describe_outputs(cls) -> List[OutputDefinition]:
100+
return [
101+
OutputDefinition(
102+
name="output",
103+
kind=[STRING_KIND, LANGUAGE_MODEL_OUTPUT_KIND],
104+
description="The model's text answer for each input image.",
105+
),
106+
]
107+
108+
@classmethod
109+
def get_parameters_accepting_batches(cls) -> List[str]:
110+
return ["images"]
111+
112+
@classmethod
113+
def get_execution_engine_compatibility(cls) -> Optional[str]:
114+
return ">=1.3.0,<2.0.0"
115+
116+
@classmethod
117+
def get_restrictions(cls) -> List[RuntimeRestriction]:
118+
restrictions = [
119+
RuntimeRestriction(
120+
severity=Severity.HARD,
121+
note="Requires a GPU; run_locally() loads a model that needs CUDA.",
122+
applies_to_runtimes=[Runtime.SELF_HOSTED_CPU],
123+
applies_to_step_execution_modes=[StepExecutionMode.LOCAL],
124+
),
125+
]
126+
if not COSMOS3_ENABLED:
127+
restrictions.append(
128+
RuntimeRestriction(
129+
severity=Severity.HARD,
130+
note=(
131+
"COSMOS3_ENABLED=False: the Cosmos 3 Edge endpoint is not "
132+
"registered, so run_remotely() returns 404."
133+
),
134+
applies_to_runtimes=[Runtime.HOSTED_SERVERLESS],
135+
applies_to_step_execution_modes=[StepExecutionMode.REMOTE],
136+
)
137+
)
138+
return restrictions
139+
140+
@classmethod
141+
def get_supported_model_variants(cls) -> Optional[List[str]]:
142+
"""Return list of model_id variants that can satisfy this block."""
143+
return ["nvidia/cosmos-3-edge"]
144+
145+
146+
class Cosmos3EdgeBlockV1(WorkflowBlock):
147+
def __init__(
148+
self,
149+
model_manager: ModelManager,
150+
api_key: Optional[str],
151+
step_execution_mode: StepExecutionMode,
152+
):
153+
self._model_manager = model_manager
154+
self._api_key = api_key
155+
self._step_execution_mode = step_execution_mode
156+
157+
@classmethod
158+
def get_init_parameters(cls) -> List[str]:
159+
return ["model_manager", "api_key", "step_execution_mode"]
160+
161+
@classmethod
162+
def get_manifest(cls) -> Type[WorkflowBlockManifest]:
163+
return BlockManifest
164+
165+
def run(
166+
self,
167+
images: Batch[WorkflowImageData],
168+
model_version: str,
169+
prompt: Optional[str],
170+
system_prompt: Optional[str],
171+
) -> BlockResult:
172+
if self._step_execution_mode == StepExecutionMode.LOCAL:
173+
return self.run_locally(
174+
images=images,
175+
model_version=model_version,
176+
prompt=prompt,
177+
system_prompt=system_prompt,
178+
)
179+
elif self._step_execution_mode == StepExecutionMode.REMOTE:
180+
return self.run_remotely(
181+
images=images,
182+
model_version=model_version,
183+
prompt=prompt,
184+
system_prompt=system_prompt,
185+
)
186+
else:
187+
raise ValueError(
188+
f"Unknown step execution mode: {self._step_execution_mode}"
189+
)
190+
191+
def run_remotely(
192+
self,
193+
images: Batch[WorkflowImageData],
194+
model_version: str,
195+
prompt: Optional[str],
196+
system_prompt: Optional[str],
197+
) -> BlockResult:
198+
api_url = (
199+
LOCAL_INFERENCE_API_URL
200+
if WORKFLOWS_REMOTE_API_TARGET != "hosted"
201+
else HOSTED_CORE_MODEL_URL
202+
)
203+
client = InferenceHTTPClient(
204+
api_url=api_url,
205+
api_key=self._api_key,
206+
)
207+
if WORKFLOWS_REMOTE_API_TARGET == "hosted":
208+
client.select_api_v0()
209+
210+
combined_prompt = _combine_prompt(prompt=prompt, system_prompt=system_prompt)
211+
predictions = []
212+
for image in images:
213+
result = client.infer_lmm(
214+
inference_input=image.base64_image,
215+
model_id=model_version,
216+
prompt=combined_prompt,
217+
model_id_in_path=True,
218+
)
219+
predictions.append({"output": result.get("response", result)})
220+
return predictions
221+
222+
def run_locally(
223+
self,
224+
images: Batch[WorkflowImageData],
225+
model_version: str,
226+
prompt: Optional[str],
227+
system_prompt: Optional[str],
228+
) -> BlockResult:
229+
inference_images = [
230+
i.to_inference_format(numpy_preferred=False) for i in images
231+
]
232+
combined_prompt = _combine_prompt(prompt=prompt, system_prompt=system_prompt)
233+
self._model_manager.add_model(model_id=model_version, api_key=self._api_key)
234+
235+
predictions = []
236+
for image in inference_images:
237+
request = LMMInferenceRequest(
238+
api_key=self._api_key,
239+
model_id=model_version,
240+
image=image,
241+
source="workflow-execution",
242+
prompt=combined_prompt,
243+
)
244+
prediction = self._model_manager.infer_from_request_sync(
245+
model_id=model_version, request=request
246+
)
247+
predictions.append({"output": prediction.response})
248+
return predictions
249+
250+
251+
def _combine_prompt(prompt: Optional[str], system_prompt: Optional[str]) -> str:
252+
prompt = prompt or DEFAULT_PROMPT
253+
system_prompt = system_prompt or DEFAULT_SYSTEM_PROMPT
254+
return prompt + "<system_prompt>" + system_prompt

inference/models/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ The models supported by Roboflow Inference have their own licenses. View the lic
33
| model | license | commercial license available |
44
|:--------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------:|:----------------------------:|
55
| `inference/models/clip` | [MIT](https://github.com/openai/CLIP/blob/main/LICENSE) | 👍 |
6+
| `inference/models/cosmos3` | [OpenMDW-1.1](https://openmdw.ai/license/1-1/) | 👍 |
67
| `inference/models/doctr` | [Apache 2.0](https://github.com/mindee/doctr/blob/main/LICENSE) | 👍 |
78
| `inference/models/depth_anything_v2` | [Apache 2.0](https://github.com/DepthAnything/Depth-Anything-V2/blob/main/LICENSE) | 👍 |
89
| `inference/models/depth_anything_v3` | [Apache 2.0](https://github.com/ByteDance-Seed/depth-anything-3/blob/main/LICENSE) | 👍 |
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
NVIDIA Cosmos 3 Edge is released under the OpenMDW License Agreement,
2+
version 1.1 (OpenMDW-1.1): https://openmdw.ai/license/1-1/
3+
4+
----------------------------------------------------------------------
5+
6+
OpenMDW License Agreement, version 1.1 (OpenMDW-1.1)
7+
8+
By exercising rights granted to you under this agreement, you accept and
9+
agree to its terms.
10+
11+
As used in this agreement, "Model Materials" means the materials provided
12+
to you under this agreement, consisting of: (1) one or more machine
13+
learning models (including architecture and parameters); and (2) all
14+
related artifacts (including associated data, documentation and software)
15+
that are provided to you hereunder.
16+
17+
Subject to your compliance with this agreement, permission is hereby
18+
granted, free of charge, to deal in the Model Materials without
19+
restriction, including under all copyright, patent, database, and trade
20+
secret rights included or embodied therein.
21+
22+
If you distribute any portion of the Model Materials, you shall retain in
23+
your distribution (1) a copy of this agreement, and (2) all copyright
24+
notices and other notices of origin included in the Model Materials that
25+
are applicable to your distribution.
26+
27+
If you file, maintain, or voluntarily participate in a lawsuit against
28+
any person or entity asserting that the Model Materials directly or
29+
indirectly infringe any patent or copyright, then all rights and grants
30+
made to you hereunder are terminated, unless that lawsuit was in response
31+
to a corresponding lawsuit first brought against you.
32+
33+
This agreement does not impose any restrictions or obligations with
34+
respect to any use, modification, or sharing of any outputs generated by
35+
using the Model Materials.
36+
37+
THE MODEL MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
38+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NONINFRINGEMENT,
40+
ACCURACY, OR THE ABSENCE OF LATENT OR OTHER DEFECTS OR ERRORS, WHETHER OR
41+
NOT DISCOVERABLE, ALL TO THE GREATEST EXTENT PERMISSIBLE UNDER APPLICABLE
42+
LAW.
43+
44+
YOU ARE SOLELY RESPONSIBLE FOR (1) CLEARING RIGHTS OF OTHER PERSONS THAT
45+
MAY APPLY TO THE MODEL MATERIALS OR ANY USE THEREOF, INCLUDING WITHOUT
46+
LIMITATION ANY PERSON'S COPYRIGHTS OR OTHER RIGHTS INCLUDED OR EMBODIED IN
47+
THE MODEL MATERIALS; (2) OBTAINING ANY NECESSARY CONSENTS, PERMISSIONS OR
48+
OTHER RIGHTS REQUIRED FOR ANY USE OF THE MODEL MATERIALS; OR (3)
49+
PERFORMING ANY DUE DILIGENCE OR UNDERTAKING ANY OTHER INVESTIGATIONS INTO
50+
THE MODEL MATERIALS OR ANYTHING INCORPORATED OR EMBODIED THEREIN.
51+
52+
IN NO EVENT SHALL THE PROVIDERS OF THE MODEL MATERIALS BE LIABLE FOR ANY
53+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
54+
OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MODEL
55+
MATERIALS, THE USE THEREOF OR OTHER DEALINGS THEREIN.

inference/models/cosmos3/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)