[Model] Enable online FP8 linears for LingBot World (#7549)
Signed-off-by: tsinghua-code <zr-liu25@mails.tsinghua.edu.cn>
This commit is contained in:
1 parent
5e28163ba5
commit
e5c0afc994
7 files changed
+129
-24
No files matched your search
@@ -213,6 +213,47 @@ accepts:
|
|||||||
`s`, `d`, `i`, `j`, `k`, and `l`;
|
`s`, `d`, `i`, `j`, `k`, and `l`;
|
||||||
- `lingbot.camera_trajectory.v1` for explicit pose/intrinsics trajectories.
|
- `lingbot.camera_trajectory.v1` for explicit pose/intrinsics trajectories.
|
||||||
|
|
||||||
|
## Online FP8 linear layers (experimental)
|
||||||
|
|
||||||
|
Pass `quantization_config={"method": "fp8"}` to the existing `AsyncOmni`
|
||||||
|
construction to use vLLM's online FP8 linear implementation. On the tested
|
||||||
|
Hopper-class GPU this dispatches to CUTLASS FP8 GEMM with online per-tensor
|
||||||
|
activation scaling; no LingBot-specific quantization kernel is introduced.
|
||||||
|
|
||||||
|
Only the transformer's existing vLLM parallel linear layers are eligible:
|
||||||
|
self-attention, cross-attention, FFN, camera injectors, and C2WS projections.
|
||||||
|
The ordinary PyTorch linear layers (including the output head and
|
||||||
|
time/text embeddings), normalization, convolutions, VAE, text encoder, and
|
||||||
|
AR KV cache are not converted to FP8 by this option.
|
||||||
|
|
||||||
|
Quality-sensitive projections can remain BF16 through fully qualified
|
||||||
|
`ignored_layers` names. For example, the following configuration tests
|
||||||
|
retaining the camera/C2WS path in BF16:
|
||||||
|
|
||||||
|
```python
|
||||||
|
quantization_config = {
|
||||||
|
"method": "fp8",
|
||||||
|
"ignored_layers": [
|
||||||
|
f"transformer.blocks.{i}.cam_injector_layer{j}"
|
||||||
|
for i in range(40)
|
||||||
|
for j in (1, 2)
|
||||||
|
]
|
||||||
|
+ [
|
||||||
|
"transformer.c2ws_hidden_states_layer1",
|
||||||
|
"transformer.c2ws_hidden_states_layer2",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Use `transformer.blocks.<i>.self_attn.qkv` to exclude the fused Q/K/V
|
||||||
|
projection as a unit. The example exclusion list is an ablation, not a
|
||||||
|
universal quality guarantee or a default. Validate the intended scene, seed,
|
||||||
|
camera trajectory, and session length against BF16 before selecting a policy.
|
||||||
|
An FP8 kernel speedup alone is not an end-to-end performance claim.
|
||||||
|
The long-session E8 quality gate in
|
||||||
|
[#7074](https://github.com/vllm-project/vllm-omni/issues/7074) remains required
|
||||||
|
for Tier-2 acceptance.
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
Real-checkpoint validation uses 480x832 output, four DMD steps, and seed 42.
|
Real-checkpoint validation uses 480x832 output, four DMD steps, and seed 42.
|
||||||
@@ -246,7 +287,7 @@ tested commit.
|
|||||||
AR blocks in one request. `max_num_seqs` must be one in both cases.
|
AR blocks in one request. `max_num_seqs` must be one in both cases.
|
||||||
- Stateful streaming VAE decode is not implemented; the realtime example emits
|
- Stateful streaming VAE decode is not implemented; the realtime example emits
|
||||||
latent chunks.
|
latent chunks.
|
||||||
- SP/USP, pipeline/CFG parallelism, HSDP, VAE parallelism, quantization,
|
- SP/USP, pipeline/CFG parallelism, HSDP, VAE parallelism, quantization methods other than online FP8,
|
||||||
Cache-DiT, TeaCache, causal-pretrain, and the 1.3B checkpoint are not claimed.
|
Cache-DiT, TeaCache, causal-pretrain, and the 1.3B checkpoint are not claimed.
|
||||||
- No AMD GPU, Ascend NPU, or Intel GPU support is claimed.
|
- No AMD GPU, Ascend NPU, or Intel GPU support is claimed.
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ def _install_vllm_stubs() -> None:
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.quant_config = kwargs.pop("quant_config", None)
|
||||||
|
self.prefix = kwargs.pop("prefix", "")
|
||||||
del kwargs
|
del kwargs
|
||||||
self.return_bias = return_bias
|
self.return_bias = return_bias
|
||||||
self.weight = nn.Parameter(torch.empty(output_size, input_size))
|
self.weight = nn.Parameter(torch.empty(output_size, input_size))
|
||||||
@@ -164,6 +166,8 @@ def _install_vllm_stubs() -> None:
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.quant_config = kwargs.pop("quant_config", None)
|
||||||
|
self.prefix = kwargs.pop("prefix", "")
|
||||||
del kwargs
|
del kwargs
|
||||||
self.num_heads = total_num_heads
|
self.num_heads = total_num_heads
|
||||||
self.num_kv_heads = total_num_kv_heads or total_num_heads
|
self.num_kv_heads = total_num_kv_heads or total_num_heads
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ def _tiny_model(
|
|||||||
num_layers: int = 2,
|
num_layers: int = 2,
|
||||||
num_frames_per_block: int = 1,
|
num_frames_per_block: int = 1,
|
||||||
sliding_window_num_frames: int = 3,
|
sliding_window_num_frames: int = 3,
|
||||||
|
quant_config=None,
|
||||||
|
prefix: str = "",
|
||||||
attention_head_dim: int = 2,
|
attention_head_dim: int = 2,
|
||||||
rope_max_seq_len: int = 16,
|
rope_max_seq_len: int = 16,
|
||||||
):
|
):
|
||||||
@@ -55,6 +57,8 @@ def _tiny_model(
|
|||||||
num_frames_per_block=num_frames_per_block,
|
num_frames_per_block=num_frames_per_block,
|
||||||
sliding_window_num_frames=sliding_window_num_frames,
|
sliding_window_num_frames=sliding_window_num_frames,
|
||||||
local_attn_size=-1,
|
local_attn_size=-1,
|
||||||
|
quant_config=quant_config,
|
||||||
|
prefix=prefix,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -485,11 +489,52 @@ def test_constructor_rejects_non_null_image_embedding_fields(field: str) -> None
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.cpu
|
@pytest.mark.cpu
|
||||||
def test_constructor_rejects_unsupported_quantization_with_runtime_error() -> None:
|
@pytest.mark.parametrize("prefix", ["", "transformer"])
|
||||||
|
@pytest.mark.parametrize("quantized", [False, True])
|
||||||
|
def test_constructor_propagates_quantization_to_parallel_linears(prefix: str, quantized: bool) -> None:
|
||||||
module = attention_tests._load_module()
|
module = attention_tests._load_module()
|
||||||
|
quant_config = object() if quantized else None
|
||||||
|
model = _tiny_model(module, num_layers=1, quant_config=quant_config, prefix=prefix)
|
||||||
|
block = model.blocks[0]
|
||||||
|
quantized_linears = [
|
||||||
|
model.c2ws_hidden_states_layer1,
|
||||||
|
model.c2ws_hidden_states_layer2,
|
||||||
|
block.self_attn.qkv,
|
||||||
|
block.self_attn.o,
|
||||||
|
block.cross_attn.q,
|
||||||
|
block.cross_attn.k,
|
||||||
|
block.cross_attn.v,
|
||||||
|
block.cross_attn.o,
|
||||||
|
block.ffn[0],
|
||||||
|
block.ffn[2],
|
||||||
|
block.cam_injector_layer1,
|
||||||
|
block.cam_injector_layer2,
|
||||||
|
]
|
||||||
|
|
||||||
with pytest.raises(RuntimeError, match="quant_config.*not supported"):
|
assert len(quantized_linears) == 12
|
||||||
module.CausalLingBotWorldTransformer3DModel(quant_config=object())
|
assert all(layer.quant_config is quant_config for layer in quantized_linears)
|
||||||
|
expected_names = {
|
||||||
|
"c2ws_hidden_states_layer1",
|
||||||
|
"c2ws_hidden_states_layer2",
|
||||||
|
*(
|
||||||
|
f"blocks.0.{name}"
|
||||||
|
for name in (
|
||||||
|
"self_attn.qkv",
|
||||||
|
"self_attn.o",
|
||||||
|
"cross_attn.q",
|
||||||
|
"cross_attn.k",
|
||||||
|
"cross_attn.v",
|
||||||
|
"cross_attn.o",
|
||||||
|
"ffn.0",
|
||||||
|
"ffn.2",
|
||||||
|
"cam_injector_layer1",
|
||||||
|
"cam_injector_layer2",
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
assert {layer.prefix for layer in quantized_linears} == {
|
||||||
|
f"{prefix}.{name}" if prefix else name for name in expected_names
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.cpu
|
@pytest.mark.cpu
|
||||||
|
|||||||
@@ -889,13 +889,14 @@ def test_unsupported_sp_config_fails_before_component_loading(overrides):
|
|||||||
assert module._loader_state.prefetch_calls == []
|
assert module._loader_state.prefetch_calls == []
|
||||||
|
|
||||||
|
|
||||||
def test_unsupported_quantization_fails_before_component_loading() -> None:
|
def test_quantization_reaches_transformer_factory() -> None:
|
||||||
module = _load_pipeline_module()
|
module = _load_pipeline_module()
|
||||||
|
quant_config = object()
|
||||||
|
|
||||||
with pytest.raises(NotImplementedError, match="quantization"):
|
pipeline = module.LingBotWorldCausalDMDPipeline(od_config=_od_config(quantization_config=quant_config))
|
||||||
module.LingBotWorldCausalDMDPipeline(od_config=_od_config(quantization_config=object()))
|
|
||||||
|
|
||||||
assert module._loader_state.prefetch_calls == []
|
assert pipeline.transformer is not None
|
||||||
|
assert _FakeTransformerFactory.last_call[1:] == (quant_config, "transformer")
|
||||||
|
|
||||||
|
|
||||||
def test_official_scheduler_config_matches_fixed_dmd_contract() -> None:
|
def test_official_scheduler_config_matches_fixed_dmd_contract() -> None:
|
||||||
|
|||||||
@@ -563,19 +563,19 @@ def test_from_cli_args_preserves_text_encoder_tp_size():
|
|||||||
def test_text_encoder_tp_size_reaches_default_diffusion_parallel_config():
|
def test_text_encoder_tp_size_reaches_default_diffusion_parallel_config():
|
||||||
"""The preserved CLI value must land in DiffusionParallelConfig.
|
"""The preserved CLI value must land in DiffusionParallelConfig.
|
||||||
|
|
||||||
Mirrors the library flow: from_cli_args -> kwargs -> the generic
|
Forward the preserved explicit override to the generic diffusion
|
||||||
diffusion fallback, which resolves the field through
|
fallback, which resolves it through
|
||||||
``DiffusionParallelConfig.from_stage_overrides``.
|
``DiffusionParallelConfig.from_stage_overrides``. Serializing all engine
|
||||||
|
defaults would also forward unrelated LLM-only fields to strict diffusion
|
||||||
|
ingress, unlike the explicit-kwargs library entrypoint.
|
||||||
"""
|
"""
|
||||||
from dataclasses import asdict
|
|
||||||
|
|
||||||
from vllm_omni.config.config_factory import StageConfigFactory
|
from vllm_omni.config.config_factory import StageConfigFactory
|
||||||
|
|
||||||
engine_args = OmniEngineArgs.from_cli_args(
|
engine_args = OmniEngineArgs.from_cli_args(
|
||||||
SimpleNamespace(text_encoder_tp_size=2),
|
SimpleNamespace(text_encoder_tp_size=2),
|
||||||
)
|
)
|
||||||
stage_cfg = StageConfigFactory.create_default_diffusion(
|
stage_cfg = StageConfigFactory.create_default_diffusion(
|
||||||
{k: v for k, v in asdict(engine_args).items() if v is not None},
|
{"text_encoder_tp_size": engine_args.text_encoder_tp_size},
|
||||||
)[0]
|
)[0]
|
||||||
|
|
||||||
parallel_config = stage_cfg["engine_args"]["parallel_config"]
|
parallel_config = stage_cfg["engine_args"]["parallel_config"]
|
||||||
|
|||||||
@@ -241,8 +241,6 @@ def _validate_scheduler_config(config: dict[str, Any]) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def _validate_parallel_config(od_config: OmniDiffusionConfig) -> None:
|
def _validate_parallel_config(od_config: OmniDiffusionConfig) -> None:
|
||||||
if getattr(od_config, "quantization_config", None) is not None:
|
|
||||||
raise NotImplementedError("LingBot World v1 does not support quantization.")
|
|
||||||
parallel_config = getattr(od_config, "parallel_config", None)
|
parallel_config = getattr(od_config, "parallel_config", None)
|
||||||
if parallel_config is None:
|
if parallel_config is None:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import math
|
|||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from typing import Any, Self, cast
|
from typing import TYPE_CHECKING, Any, Self, cast
|
||||||
|
|
||||||
import torch
|
import torch
|
||||||
import torch.nn as nn
|
import torch.nn as nn
|
||||||
@@ -36,6 +36,9 @@ from vllm_omni.experimental.ar_diffusion.kv_cache.paged_attention import (
|
|||||||
paged_write_attn,
|
paged_write_attn,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from vllm.model_executor.layers.quantization.base_config import QuantizationConfig
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LingBotAttentionCache:
|
class LingBotAttentionCache:
|
||||||
@@ -170,6 +173,7 @@ class LingBotSelfAttention(nn.Module):
|
|||||||
num_heads: int,
|
num_heads: int,
|
||||||
*,
|
*,
|
||||||
eps: float = 1e-6,
|
eps: float = 1e-6,
|
||||||
|
quant_config: QuantizationConfig | None = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -188,6 +192,7 @@ class LingBotSelfAttention(nn.Module):
|
|||||||
head_size=self.head_dim,
|
head_size=self.head_dim,
|
||||||
total_num_heads=num_heads,
|
total_num_heads=num_heads,
|
||||||
bias=True,
|
bias=True,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "qkv"),
|
prefix=_projection_prefix(prefix, "qkv"),
|
||||||
)
|
)
|
||||||
self.num_local_heads = self.qkv.num_heads
|
self.num_local_heads = self.qkv.num_heads
|
||||||
@@ -205,6 +210,7 @@ class LingBotSelfAttention(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
input_is_parallel=True,
|
input_is_parallel=True,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "o"),
|
prefix=_projection_prefix(prefix, "o"),
|
||||||
)
|
)
|
||||||
self.norm_q = _LingBotRMSNorm(self.tp_inner_dim, eps)
|
self.norm_q = _LingBotRMSNorm(self.tp_inner_dim, eps)
|
||||||
@@ -416,6 +422,7 @@ class LingBotCrossAttention(nn.Module):
|
|||||||
num_heads: int,
|
num_heads: int,
|
||||||
*,
|
*,
|
||||||
eps: float = 1e-6,
|
eps: float = 1e-6,
|
||||||
|
quant_config: QuantizationConfig | None = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -443,6 +450,7 @@ class LingBotCrossAttention(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "q"),
|
prefix=_projection_prefix(prefix, "q"),
|
||||||
)
|
)
|
||||||
self.k = ColumnParallelLinear(
|
self.k = ColumnParallelLinear(
|
||||||
@@ -451,6 +459,7 @@ class LingBotCrossAttention(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "k"),
|
prefix=_projection_prefix(prefix, "k"),
|
||||||
)
|
)
|
||||||
self.v = ColumnParallelLinear(
|
self.v = ColumnParallelLinear(
|
||||||
@@ -459,6 +468,7 @@ class LingBotCrossAttention(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "v"),
|
prefix=_projection_prefix(prefix, "v"),
|
||||||
)
|
)
|
||||||
self.o = RowParallelLinear(
|
self.o = RowParallelLinear(
|
||||||
@@ -467,6 +477,7 @@ class LingBotCrossAttention(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
input_is_parallel=True,
|
input_is_parallel=True,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "o"),
|
prefix=_projection_prefix(prefix, "o"),
|
||||||
)
|
)
|
||||||
self.norm_q = _LingBotRMSNorm(self.tp_inner_dim, eps)
|
self.norm_q = _LingBotRMSNorm(self.tp_inner_dim, eps)
|
||||||
@@ -528,6 +539,7 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
ffn_dim: int | None = None,
|
ffn_dim: int | None = None,
|
||||||
cross_attn_norm: bool = True,
|
cross_attn_norm: bool = True,
|
||||||
eps: float = 1e-6,
|
eps: float = 1e-6,
|
||||||
|
quant_config: QuantizationConfig | None = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -538,12 +550,14 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
dim,
|
dim,
|
||||||
num_heads,
|
num_heads,
|
||||||
eps=eps,
|
eps=eps,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "self_attn"),
|
prefix=_projection_prefix(prefix, "self_attn"),
|
||||||
)
|
)
|
||||||
self.cross_attn = LingBotCrossAttention(
|
self.cross_attn = LingBotCrossAttention(
|
||||||
dim,
|
dim,
|
||||||
num_heads,
|
num_heads,
|
||||||
eps=eps,
|
eps=eps,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "cross_attn"),
|
prefix=_projection_prefix(prefix, "cross_attn"),
|
||||||
)
|
)
|
||||||
self.norm2 = LayerNorm(dim, eps=eps, elementwise_affine=False)
|
self.norm2 = LayerNorm(dim, eps=eps, elementwise_affine=False)
|
||||||
@@ -555,6 +569,7 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "ffn.0"),
|
prefix=_projection_prefix(prefix, "ffn.0"),
|
||||||
),
|
),
|
||||||
nn.GELU(approximate="tanh"),
|
nn.GELU(approximate="tanh"),
|
||||||
@@ -564,6 +579,7 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
input_is_parallel=True,
|
input_is_parallel=True,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "ffn.2"),
|
prefix=_projection_prefix(prefix, "ffn.2"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@@ -574,6 +590,7 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "cam_injector_layer1"),
|
prefix=_projection_prefix(prefix, "cam_injector_layer1"),
|
||||||
)
|
)
|
||||||
self.cam_injector_layer2 = RowParallelLinear(
|
self.cam_injector_layer2 = RowParallelLinear(
|
||||||
@@ -582,6 +599,7 @@ class LingBotAttentionBlock(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
input_is_parallel=True,
|
input_is_parallel=True,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "cam_injector_layer2"),
|
prefix=_projection_prefix(prefix, "cam_injector_layer2"),
|
||||||
)
|
)
|
||||||
self.cam_scale_layer = nn.Linear(dim, dim)
|
self.cam_scale_layer = nn.Linear(dim, dim)
|
||||||
@@ -823,7 +841,7 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
num_frames_per_block: int = 3,
|
num_frames_per_block: int = 3,
|
||||||
sliding_window_num_frames: int = 18,
|
sliding_window_num_frames: int = 18,
|
||||||
local_attn_size: int = -1,
|
local_attn_size: int = -1,
|
||||||
quant_config: object | None = None,
|
quant_config: QuantizationConfig | None = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -853,11 +871,6 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
):
|
):
|
||||||
if field_value is not None:
|
if field_value is not None:
|
||||||
raise ValueError(f"{field_name} must be None because LingBot World v2 has no image embedding path.")
|
raise ValueError(f"{field_name} must be None because LingBot World v2 has no image embedding path.")
|
||||||
if quant_config is not None:
|
|
||||||
raise RuntimeError(
|
|
||||||
"quant_config is not supported by the LingBot World transformer; construct the unquantized model."
|
|
||||||
)
|
|
||||||
|
|
||||||
dim = num_attention_heads * attention_head_dim
|
dim = num_attention_heads * attention_head_dim
|
||||||
self.dim = dim
|
self.dim = dim
|
||||||
self.config = SimpleNamespace(
|
self.config = SimpleNamespace(
|
||||||
@@ -898,6 +911,7 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
gather_output=False,
|
gather_output=False,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "c2ws_hidden_states_layer1"),
|
prefix=_projection_prefix(prefix, "c2ws_hidden_states_layer1"),
|
||||||
)
|
)
|
||||||
self.c2ws_hidden_states_layer2 = RowParallelLinear(
|
self.c2ws_hidden_states_layer2 = RowParallelLinear(
|
||||||
@@ -906,6 +920,7 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
bias=True,
|
bias=True,
|
||||||
input_is_parallel=True,
|
input_is_parallel=True,
|
||||||
return_bias=False,
|
return_bias=False,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, "c2ws_hidden_states_layer2"),
|
prefix=_projection_prefix(prefix, "c2ws_hidden_states_layer2"),
|
||||||
)
|
)
|
||||||
self.text_embedding = nn.Sequential(
|
self.text_embedding = nn.Sequential(
|
||||||
@@ -930,6 +945,7 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
ffn_dim=ffn_dim,
|
ffn_dim=ffn_dim,
|
||||||
cross_attn_norm=cross_attn_norm,
|
cross_attn_norm=cross_attn_norm,
|
||||||
eps=eps,
|
eps=eps,
|
||||||
|
quant_config=quant_config,
|
||||||
prefix=_projection_prefix(prefix, f"blocks.{index}"),
|
prefix=_projection_prefix(prefix, f"blocks.{index}"),
|
||||||
)
|
)
|
||||||
for index in range(num_layers)
|
for index in range(num_layers)
|
||||||
@@ -976,7 +992,7 @@ class CausalLingBotWorldTransformer3DModel(nn.Module):
|
|||||||
cls,
|
cls,
|
||||||
config: dict[str, Any],
|
config: dict[str, Any],
|
||||||
*,
|
*,
|
||||||
quant_config: Any | None = None,
|
quant_config: QuantizationConfig | None = None,
|
||||||
prefix: str = "",
|
prefix: str = "",
|
||||||
) -> Self:
|
) -> Self:
|
||||||
checkpoint_contract = {
|
checkpoint_contract = {
|
||||||
|
|||||||
Reference in new issue
Block a user