콘텐츠로 이동

Cosmos-Reason2(VLM)

개요

Cosmos-Reason2는 Cosmos-Reason1의 다음 세대 모델로, 비디오와 이미지 입력에 담긴 공간, 시간, 기본 물리 법칙을 이해하는 Physical AI 비전 언어 모델(VLM)입니다. Qwen3-VL-Instruct를 물리 상식 및 embodied reasoning 데이터로 사후 학습한 모델이며, 최종 답변 이전에 긴 chain-of-thought 추론 과정을 생성하기 때문에 embodied agent의 계획 모델로도 활용할 수 있습니다. 모델 제품군은 2B, 8B, 32B 세 가지로 구성되며, 최대 256K 토큰의 멀티모달 컨텍스트를 지원합니다. 이 튜토리얼에서는 RBLN Optimum(optimum-rbln)을 사용하여 Cosmos-Reason2-2B 모델을 여러 개의 RBLN NPU용으로 컴파일하고, 입력 비디오에 대한 질문에 답변하는 방법을 보여줍니다.

Info

리벨리온 확장형 설계(Rebellions Scalable Design, RSD)는 ATOM™+ (RBLN-CA22)와 ATOM™-Max(RBLN-CA25)에서 사용 가능합니다. 현재 사용 중인 RBLN NPU 종류는 rbln-stat 명령어로 확인할 수 있습니다.

환경 설정 및 설치 확인

시작하기 전에 시스템 환경이 올바르게 구성되어 있고 필요한 패키지가 모두 설치되어 있는지 확인합니다. 필요한 항목은 다음과 같습니다:

Note

  • RBLN Compiler를 사용하려면 RBLN 포털 계정이 필요합니다.
  • 위 명령은 Debian 계열 Linux(예: Ubuntu)에서 pip로 패키지를 설치하는 일반적인 절차를 전제로 합니다. OS나 환경이 다른 경우에는 설치 가이드에서 지원되는 설치 조합과 적용 가능한 명령을 확인할 수 있습니다.

Note

nvidia/Cosmos-Reason2-2B 모델은 접근이 제한되어 있습니다(gated model). HuggingFace에서 NVIDIA Open Model License에 동의하여 접근 권한을 부여받은 후, 아래와 같이 hf auth(huggingface-cli) 명령어를 사용하여 로그인할 수 있습니다.

$ hf auth login

    _|    _|  _|    _|    _|_|_|    _|_|_|  _|_|_|  _|      _|    _|_|_|      _|_|_|_|    _|_|      _|_|_|  _|_|_|_|
    _|    _|  _|    _|  _|        _|          _|    _|_|    _|  _|            _|        _|    _|  _|        _|
    _|_|_|_|  _|    _|  _|  _|_|  _|  _|_|    _|    _|  _|  _|  _|  _|_|      _|_|_|    _|_|_|_|  _|        _|_|_|
    _|    _|  _|    _|  _|    _|  _|    _|    _|    _|    _|_|  _|    _|      _|        _|    _|  _|        _|
    _|    _|    _|_|      _|_|_|    _|_|_|  _|_|_|  _|      _|    _|_|_|      _|        _|    _|    _|_|_|  _|_|_|_|

    To login, `huggingface_hub` requires a token generated from https://huggingface.co/settings/tokens.
Enter your token (input will not be visible):

RBLN Optimum(optimum-rbln) 라이브러리를 사용하여 실행하기

이 단계에서는 여러 개의 RBLN NPU에서 실행되도록 Cosmos-Reason2 모델을 컴파일합니다.

다중 NPU 대상 모델 컴파일

먼저 optimum-rbln에서 RBLNAutoModelForImageTextToText 클래스를 가져옵니다. 이 클래스의 from_pretrained() 메서드는 HuggingFace 허브에서 Cosmos-Reason2 모델을 다운로드하고 RBLN Compiler를 사용하여 컴파일합니다. Cosmos-Reason2는 비전 인코더가 언어 모델의 visual 서브모듈로 선언되는 Qwen3-VL 구조를 따르므로, 아래 rbln_config도 이에 맞추어 중첩된 형태로 지정합니다. 모델을 컴파일하려면 export 인수를 True로 설정합니다. 아래 예제는 비전 인코더와 언어 모델을 각각 NPU 8개에 컴파일하며, 두 레벨의 create_runtimes를 False로 설정하여 컴파일 시 NPU 런타임을 생성하지 않습니다.

컴파일 후에는 save_pretrained() 메서드를 사용하여 모델 아티팩트를 디스크에 저장합니다. 이 과정은 컴파일된 모델을 포함하는 디렉터리(예: rbln-cosmos-reason2)를 생성합니다.

Tip

중첩된 rbln_config의 각 필드와, 여러 입력 해상도 또는 디코더 배치 크기를 한 번의 컴파일로 지원하는 버케팅(bucketing) 옵션은 Qwen3-VL-2B(VLM)에 정리되어 있습니다.

Note

Cosmos-Reason2-8B는 동일한 아키텍처와 동일한 컴파일 설정을 사용하므로, model_id만 변경하여 컴파일할 수 있습니다. Cosmos-Reason2-32B는 언어 모델이 더 크기 때문에 num_devices를 16으로 설정하고, 비전 인코더는 8을 유지하며, 모델을 불러올 때 device에도 NPU 16개를 전달해야 합니다.

from optimum.rbln import RBLNAutoModelForImageTextToText

# Define the HuggingFace model ID
model_id = "nvidia/Cosmos-Reason2-2B"

# Compile the model for 8 RBLN NPUs
model = RBLNAutoModelForImageTextToText.from_pretrained(
    model_id,
    export=True,
    attn_implementation="sdpa",
    rbln_config={
        "visual": {
            "max_seq_len": 16_384,
            "num_devices": 8,
            "create_runtimes": False,
        },
        "num_devices": 8,
        "kvcache_partition_len": 16_384,
        "max_seq_len": 262_144,
        "create_runtimes": False,
    },
)
# Save all compiled results to disk
model.save_pretrained("rbln-cosmos-reason2")

컴파일된 RBLN 모델 불러오기

RBLNAutoModelForImageTextToText.from_pretrained()를 사용하여 컴파일된 RBLN 모델을 불러옵니다. 저장된 디렉터리 경로를 model_id로 전달하고 export 인수를 False로 설정합니다.

Cosmos-Reason2는 비전 인코더와 언어 모델로 구성되어 있으며, 두 모듈을 하나의 NPU에 함께 불러오면 디바이스 메모리 용량을 초과할 수 있습니다. 따라서 rbln_config의 device 인수로 각 서브모듈이 사용할 NPU를 지정합니다. 아래 예제 코드에서는 비전 인코더와 언어 모델이 동일한 8개의 NPU를 공유합니다.

from optimum.rbln import RBLNAutoModelForImageTextToText

# Load the compiled RBLN model from the specified directory
model = RBLNAutoModelForImageTextToText.from_pretrained(
    model_id="rbln-cosmos-reason2",
    export=False,
    rbln_config={
        "visual": {
            "device": [0, 1, 2, 3, 4, 5, 6, 7],
        },
        "device": [0, 1, 2, 3, 4, 5, 6, 7],
    },
)

입력 준비하기

transformers 라이브러리의 AutoProcessor를 사용하여 채팅 메시지 목록에서 모델 입력을 구성합니다. apply_chat_template() 메서드는 메시지에 지정된 비디오를 디코딩하여 프레임을 샘플링하고, 전체 프롬프트를 토큰화하는 과정을 한 번의 호출로 처리합니다.

Note

입력 비디오는 Cosmos-Reason2의 학습 환경과 동일하게 4 FPS로 샘플링하는 것을 권장합니다. 텍스트 프롬프트에 덧붙인 답변 형식은 모델이 <think> 블록으로 감싸인 chain-of-thought 추론 과정을 생성하도록 유도합니다.

from transformers import AutoProcessor

processor = AutoProcessor.from_pretrained("rbln-cosmos-reason2")

video_messages = [
    {
        "role": "system",
        "content": [{"type": "text", "text": "You are a helpful assistant."}],
    },
    {
        "role": "user",
        "content": [
            {
                "type": "video",
                "url": "https://raw.githubusercontent.com/nvidia-cosmos/cosmos-reason1/main/assets/sample.mp4",
                "fps": 4,
            },
            {
                "type": "text",
                "text": (
                    "Is it safe to turn right? Answer the question using the following format:\n\n<think>\nYour reasoning.\n</think>\n\nWrite your final answer immediately after the </think> tag."
                ),
            },
        ],
    },
]

# Process inputs
inputs = processor.apply_chat_template(
    video_messages,
    tokenize=True,
    add_generation_prompt=True,
    return_dict=True,
    return_tensors="pt",
    fps=4,
)

모델 추론

이제 generate() 메서드를 사용하여 응답을 생성할 수 있습니다. 생성된 시퀀스에서 프롬프트 토큰을 제외한 뒤, 남은 토큰을 디코딩하여 답변을 확인합니다.

Note

max_new_tokens는 4096 이상으로 유지해야 합니다. chain-of-thought 방식의 답변은 길기 때문에, 이보다 작은 값을 사용하면 최종 답변에 도달하기 전에 응답이 잘립니다.

# autoregressively complete prompt
generated_ids = model.generate(**inputs, max_new_tokens=4096)
generated_ids_trimmed = [
    out_ids[len(in_ids) :]
    for in_ids, out_ids in zip(inputs.input_ids, generated_ids, strict=False)
]

output_text = processor.batch_decode(
    generated_ids_trimmed,
    skip_special_tokens=True,
    clean_up_tokenization_spaces=False,
)
# Show text and result
print(f"Result: {output_text}")

예시 출력:

1
2
3
4
5
6
7
8
<think>
Okay, let's try to figure out if it's safe to turn right based on the video. First, the video shows a residential street with parked cars on both sides. The ego vehicle is approaching an intersection where there are parked cars on the left and right.
...
Since the ego is waiting at a stop sign, they need to check for any oncoming traffic, pedestrians, or cyclists before turning. The video doesn't show any traffic coming from the opposite direction, but in a residential area, there could be cars backing out of driveways or pedestrians. The presence of a stop sign means they must yield to any cross traffic or pedestrians before turning right.
</think>

...
Once the crosswalk is confirmed clear, the turn would be safe.

전체 예제 코드는 RBLN Model Zoo GitHub 저장소에서 확인할 수 있습니다.

참고