Upload folder using huggingface_hub
Browse files- __pycache__/configuration_cosyvoice2.cpython-312.pyc +0 -0
- __pycache__/configuration_hyperclovax.cpython-312.pyc +0 -0
- __pycache__/configuration_mambamia.cpython-312.pyc +0 -0
- __pycache__/configuration_tatok.cpython-312.pyc +0 -0
- audio_processing_hyperclovax_omni.py +162 -132
- chat_template.jinja +2 -2
- config.json +5 -377
- configuration_cosyvoice2.py +57 -94
- configuration_hyperclovax.py +63 -72
- configuration_hyperclovax_omni.py +158 -131
- configuration_mambamia.py +36 -12
- configuration_tatok.py +68 -120
- image_processing_hyperclovax_omni.py +172 -119
- modeling_hyperclovax_omni.py +17 -21
- preprocessor_config.json +1 -1
- processing_hyperclovax_omni.py +103 -104
- tokenizer.json +2 -2
- tokenizer_config.json +2 -2
- video_processing_hyperclovax_omni.py +110 -73
__pycache__/configuration_cosyvoice2.cpython-312.pyc
ADDED
|
Binary file (2.63 kB). View file
|
|
|
__pycache__/configuration_hyperclovax.cpython-312.pyc
ADDED
|
Binary file (11.4 kB). View file
|
|
|
__pycache__/configuration_mambamia.cpython-312.pyc
ADDED
|
Binary file (2.19 kB). View file
|
|
|
__pycache__/configuration_tatok.cpython-312.pyc
ADDED
|
Binary file (3.42 kB). View file
|
|
|
audio_processing_hyperclovax_omni.py
CHANGED
|
@@ -1,10 +1,21 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import numpy as np
|
| 3 |
-
|
| 4 |
from transformers import BatchFeature
|
| 5 |
-
from transformers.
|
| 6 |
from transformers.feature_extraction_sequence_utils import SequenceFeatureExtractor
|
| 7 |
-
from transformers.
|
| 8 |
|
| 9 |
|
| 10 |
class HyperCLOVAXOmniAudioKwargs(AudioKwargs, total=False):
|
|
@@ -29,6 +40,13 @@ class HyperCLOVAXOmniAudioKwargs(AudioKwargs, total=False):
|
|
| 29 |
|
| 30 |
|
| 31 |
class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
model_input_names = ["audio_values", "audio_masks", "discrete_audio_values"]
|
| 33 |
|
| 34 |
def __init__(
|
|
@@ -93,17 +111,21 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 93 |
mel_scale="slaney",
|
| 94 |
)
|
| 95 |
|
| 96 |
-
def _extract_fbank_features(
|
| 97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 98 |
|
| 99 |
-
WhisperFeatureExtractor._torch_extract_fbank_features
|
| 100 |
|
| 101 |
Args:
|
| 102 |
-
waveform_batch: (batch_size, n_samples)
|
| 103 |
-
device:
|
| 104 |
|
| 105 |
Returns:
|
| 106 |
-
(batch_size, feature_size, num_frames)
|
| 107 |
"""
|
| 108 |
waveform = torch.from_numpy(waveform_batch).to(device, torch.float32)
|
| 109 |
window = torch.hann_window(self.n_fft, device=device)
|
|
@@ -135,20 +157,19 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 135 |
chunks: List[np.ndarray],
|
| 136 |
sampling_rate: int,
|
| 137 |
) -> dict:
|
| 138 |
-
"""
|
| 139 |
|
| 140 |
-
|
| 141 |
-
attention mask
|
| 142 |
-
핵심 로직을 대체합니다.
|
| 143 |
|
| 144 |
Args:
|
| 145 |
-
chunks: 1D numpy
|
| 146 |
-
sampling_rate:
|
| 147 |
|
| 148 |
Returns:
|
| 149 |
-
|
| 150 |
-
- "input_features": (num_chunks, feature_size, nb_max_frames)
|
| 151 |
-
- "attention_mask": (num_chunks, nb_max_frames)
|
| 152 |
"""
|
| 153 |
n_samples = self.chunk_length * sampling_rate
|
| 154 |
nb_max_frames = n_samples // self.hop_length
|
|
@@ -160,7 +181,7 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 160 |
chunk = np.asarray(chunk, dtype=np.float32)
|
| 161 |
chunk_len = len(chunk)
|
| 162 |
|
| 163 |
-
#
|
| 164 |
if chunk_len < n_samples:
|
| 165 |
padded = np.full(n_samples, self.padding_value, dtype=np.float32)
|
| 166 |
padded[:chunk_len] = chunk
|
|
@@ -170,11 +191,10 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 170 |
|
| 171 |
padded_waveforms.append(padded)
|
| 172 |
|
| 173 |
-
# Attention mask (sample-level
|
| 174 |
sample_mask = np.zeros(n_samples, dtype=np.int32)
|
| 175 |
sample_mask[:chunk_len] = 1
|
| 176 |
frame_mask = sample_mask[:: self.hop_length]
|
| 177 |
-
# nb_max_frames 길이로 맞춤
|
| 178 |
if len(frame_mask) > nb_max_frames:
|
| 179 |
frame_mask = frame_mask[:nb_max_frames]
|
| 180 |
elif len(frame_mask) < nb_max_frames:
|
|
@@ -190,75 +210,32 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 190 |
"attention_mask": attention_mask,
|
| 191 |
}
|
| 192 |
|
| 193 |
-
def
|
| 194 |
-
|
| 195 |
-
audio_masks: "torch.Tensor",
|
| 196 |
-
discrete_audio_values: Optional["torch.Tensor"] = None,
|
| 197 |
-
include_boundary_tokens: bool = False,
|
| 198 |
-
chunk_unit: Optional[int] = None,
|
| 199 |
-
sampling_rate: Optional[int] = None,
|
| 200 |
-
) -> tuple:
|
| 201 |
-
"""오디오 입력에 대한 (continuous, discrete) 토큰 수를 계산합니다.
|
| 202 |
|
| 203 |
Args:
|
| 204 |
-
audio_masks:
|
| 205 |
-
discrete_audio_values: discrete audio waveform. None이면 discrete 계산 생략.
|
| 206 |
-
include_boundary_tokens: start/end 토큰 포함 여부.
|
| 207 |
-
chunk_unit: discrete 처리 시 청크 단위 (초). None이면 self.chunk_unit 사용.
|
| 208 |
-
sampling_rate: 샘플링 레이트. None이면 self.sampling_rate 사용.
|
| 209 |
|
| 210 |
Returns:
|
| 211 |
-
(
|
| 212 |
-
discrete 미사용 시 num_discrete_tokens는 0.
|
| 213 |
"""
|
| 214 |
-
|
| 215 |
-
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 216 |
-
|
| 217 |
-
def _compute_continuous_tokens(audio_mask: "torch.Tensor") -> int:
|
| 218 |
-
input_length = (int(audio_mask.sum()) - 1) // 2 + 1
|
| 219 |
-
return (input_length - 2) // 2 + 1
|
| 220 |
-
|
| 221 |
-
num_continuous_tokens, num_discrete_tokens = 0, 0
|
| 222 |
-
if len(audio_masks.shape) == 1:
|
| 223 |
-
num_continuous_tokens = _compute_continuous_tokens(audio_masks)
|
| 224 |
-
else:
|
| 225 |
-
num_continuous_tokens = sum(_compute_continuous_tokens(m) for m in audio_masks)
|
| 226 |
-
if include_boundary_tokens:
|
| 227 |
-
num_continuous_tokens += 2 # audio_start_token, audio_end_token
|
| 228 |
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
and discrete_audio_values is not None
|
| 232 |
-
):
|
| 233 |
-
audio_length = len(discrete_audio_values)
|
| 234 |
-
chunk_size = chunk_unit * sampling_rate
|
| 235 |
-
for _start in range(0, audio_length, chunk_size):
|
| 236 |
-
_end = min(_start + chunk_size, audio_length)
|
| 237 |
-
_chunked_length = _end - _start
|
| 238 |
-
mel_len = _chunked_length // 160
|
| 239 |
-
after_conv1 = (mel_len + 2 * 1 - 1 * (3 - 1) - 1) // 2 + 1
|
| 240 |
-
code_len = (after_conv1 + 2 * 1 - 1 * (3 - 1) - 1) // 2 + 1
|
| 241 |
-
num_discrete_tokens += code_len
|
| 242 |
-
if include_boundary_tokens:
|
| 243 |
-
num_discrete_tokens += 2 # discrete_audio_start_token, discrete_audio_end_token
|
| 244 |
|
| 245 |
-
|
| 246 |
|
| 247 |
-
|
| 248 |
-
|
| 249 |
-
audio_masks: torch.Tensor,
|
| 250 |
-
):
|
| 251 |
-
return (audio_masks.sum(-1) - 1) // 2 + 1
|
| 252 |
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
audio_masks: torch.Tensor,
|
| 257 |
-
):
|
| 258 |
feature_lengths = self._get_feature_lengths(audio_masks=audio_masks)
|
| 259 |
-
max_seq_len = (self.nb_max_frames - 2) // 2 + 1
|
| 260 |
padding_mask = torch.arange(max_seq_len) >= feature_lengths.unsqueeze(1)
|
| 261 |
-
attention_mask = padding_mask[:, None, None, :].expand(
|
| 262 |
attention_mask = attention_mask.masked_fill(attention_mask, float("-inf"))
|
| 263 |
return attention_mask
|
| 264 |
|
|
@@ -268,35 +245,32 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 268 |
sampling_rate: Optional[int] = None,
|
| 269 |
chunk_length: Optional[int] = None,
|
| 270 |
) -> dict:
|
| 271 |
-
"""
|
| 272 |
|
| 273 |
-
|
| 274 |
-
|
| 275 |
|
| 276 |
Args:
|
| 277 |
-
audio_clips:
|
| 278 |
-
|
| 279 |
-
|
| 280 |
-
chunk_length: 오디오를 분할할 단위 (초). None이면 self.chunk_length 사용.
|
| 281 |
|
| 282 |
Returns:
|
| 283 |
-
|
| 284 |
-
- "audio_values": (num_total_chunks, feature_size, nb_max_frames)
|
| 285 |
-
- "audio_masks": (num_total_chunks, nb_max_frames)
|
| 286 |
-
- "
|
|
|
|
| 287 |
"""
|
| 288 |
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 289 |
chunk_length = chunk_length if chunk_length is not None else self.chunk_length
|
| 290 |
|
| 291 |
if len(audio_clips) == 0:
|
| 292 |
-
_audio_values = torch.zeros(0, self.feature_size, self.nb_max_frames)
|
| 293 |
-
_audio_masks = torch.zeros(0, self.nb_max_frames)
|
| 294 |
max_seq_len = (self.nb_max_frames - 2) // 2 + 1
|
| 295 |
-
_audio_attention_mask = torch.zeros(0, 1, max_seq_len, max_seq_len)
|
| 296 |
return {
|
| 297 |
-
"audio_values":
|
| 298 |
-
"
|
| 299 |
-
"
|
| 300 |
"num_audio_tokens": torch.tensor([], dtype=torch.long),
|
| 301 |
}
|
| 302 |
|
|
@@ -311,21 +285,19 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 311 |
|
| 312 |
_audio_value = result["input_features"]
|
| 313 |
_audio_mask = result["attention_mask"]
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
|
| 319 |
_audio_values.append(torch.Tensor(_audio_value))
|
| 320 |
_audio_masks.append(torch.Tensor(_audio_mask))
|
| 321 |
-
_num_audio_tokens.append(
|
| 322 |
|
| 323 |
_audio_values = torch.cat(_audio_values, dim=0)
|
| 324 |
_audio_masks = torch.cat(_audio_masks, dim=0)
|
| 325 |
-
_audio_attention_mask = self._get_attention_mask(
|
| 326 |
-
|
| 327 |
-
audio_masks=_audio_masks,
|
| 328 |
-
)
|
| 329 |
return {
|
| 330 |
"audio_values": _audio_values,
|
| 331 |
"audio_masks": _audio_masks,
|
|
@@ -340,23 +312,21 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 340 |
chunk_unit: Optional[int] = None,
|
| 341 |
min_chunk_size: Optional[int] = None,
|
| 342 |
) -> dict:
|
| 343 |
-
"""
|
| 344 |
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
패딩하여 텐서로 반환합니다.
|
| 348 |
|
| 349 |
Args:
|
| 350 |
-
audio_clips:
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
min_chunk_size: 최소 오디오 길이 (샘플 수). None이면 self.min_chunk_size 사용.
|
| 355 |
|
| 356 |
Returns:
|
| 357 |
-
|
| 358 |
-
- "discrete_audio_values": (N, max_audio_len)
|
| 359 |
-
- "num_discrete_audio_tokens": (N,)
|
| 360 |
"""
|
| 361 |
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 362 |
chunk_unit = chunk_unit if chunk_unit is not None else self.chunk_unit
|
|
@@ -419,26 +389,29 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 419 |
min_chunk_size: Optional[int] = None,
|
| 420 |
**kwargs,
|
| 421 |
) -> BatchFeature:
|
| 422 |
-
"""
|
| 423 |
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
수행합니다.
|
| 427 |
|
| 428 |
Args:
|
| 429 |
-
audios:
|
| 430 |
-
sampling_rate:
|
| 431 |
-
chunk_length:
|
| 432 |
-
|
| 433 |
-
|
|
|
|
|
|
|
|
|
|
| 434 |
|
| 435 |
Returns:
|
| 436 |
BatchFeature with:
|
| 437 |
-
- audio_values: (num_total_chunks, feature_size, nb_max_frames)
|
| 438 |
-
- audio_masks: (num_total_chunks, nb_max_frames)
|
| 439 |
-
-
|
| 440 |
-
-
|
| 441 |
-
-
|
|
|
|
| 442 |
"""
|
| 443 |
continuous_result = self._preprocess_continuous_audio(
|
| 444 |
audios,
|
|
@@ -464,3 +437,60 @@ class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
|
| 464 |
data["num_discrete_audio_tokens"] = discrete_result["num_discrete_audio_tokens"]
|
| 465 |
|
| 466 |
return BatchFeature(data=data, tensor_type="pt")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
HyperCLOVAX Omni Audio Processor
|
| 3 |
+
|
| 4 |
+
Implements Whisper-compatible audio feature extraction:
|
| 5 |
+
- Log-mel spectrogram extraction from waveform
|
| 6 |
+
- Chunked processing for long audio clips
|
| 7 |
+
- Attention mask generation for padded sequences
|
| 8 |
+
- Discrete audio token count calculation (conv-based)
|
| 9 |
+
"""
|
| 10 |
+
|
| 11 |
+
from typing import List, Optional
|
| 12 |
+
|
| 13 |
import numpy as np
|
| 14 |
+
import torch
|
| 15 |
from transformers import BatchFeature
|
| 16 |
+
from transformers.audio_utils import mel_filter_bank
|
| 17 |
from transformers.feature_extraction_sequence_utils import SequenceFeatureExtractor
|
| 18 |
+
from transformers.processing_utils import AudioKwargs
|
| 19 |
|
| 20 |
|
| 21 |
class HyperCLOVAXOmniAudioKwargs(AudioKwargs, total=False):
|
|
|
|
| 40 |
|
| 41 |
|
| 42 |
class HyperCLOVAXOmniAudioProcessor(SequenceFeatureExtractor):
|
| 43 |
+
"""Audio processor for HyperCLOVAX Omni.
|
| 44 |
+
|
| 45 |
+
Extracts Whisper-compatible log-mel spectrogram features and computes
|
| 46 |
+
attention masks for the audio encoder. Also supports discrete audio
|
| 47 |
+
token count calculation.
|
| 48 |
+
"""
|
| 49 |
+
|
| 50 |
model_input_names = ["audio_values", "audio_masks", "discrete_audio_values"]
|
| 51 |
|
| 52 |
def __init__(
|
|
|
|
| 111 |
mel_scale="slaney",
|
| 112 |
)
|
| 113 |
|
| 114 |
+
def _extract_fbank_features(
|
| 115 |
+
self,
|
| 116 |
+
waveform_batch: np.ndarray,
|
| 117 |
+
device: str = "cpu",
|
| 118 |
+
) -> np.ndarray:
|
| 119 |
+
"""Extract log-mel spectrogram features from a waveform batch.
|
| 120 |
|
| 121 |
+
Follows the same logic as WhisperFeatureExtractor._torch_extract_fbank_features.
|
| 122 |
|
| 123 |
Args:
|
| 124 |
+
waveform_batch: Waveform array of shape (batch_size, n_samples).
|
| 125 |
+
device: Device for computation. Defaults to "cpu".
|
| 126 |
|
| 127 |
Returns:
|
| 128 |
+
Log-mel spectrogram of shape (batch_size, feature_size, num_frames).
|
| 129 |
"""
|
| 130 |
waveform = torch.from_numpy(waveform_batch).to(device, torch.float32)
|
| 131 |
window = torch.hann_window(self.n_fft, device=device)
|
|
|
|
| 157 |
chunks: List[np.ndarray],
|
| 158 |
sampling_rate: int,
|
| 159 |
) -> dict:
|
| 160 |
+
"""Pad audio chunks and extract mel-spectrogram features.
|
| 161 |
|
| 162 |
+
Each chunk is padded to n_samples length, then mel-spectrogram is
|
| 163 |
+
extracted and an attention mask is generated.
|
|
|
|
| 164 |
|
| 165 |
Args:
|
| 166 |
+
chunks: List of 1D numpy arrays, each representing an audio chunk.
|
| 167 |
+
sampling_rate: Audio sampling rate.
|
| 168 |
|
| 169 |
Returns:
|
| 170 |
+
Dictionary with:
|
| 171 |
+
- "input_features": Array of shape (num_chunks, feature_size, nb_max_frames).
|
| 172 |
+
- "attention_mask": Array of shape (num_chunks, nb_max_frames).
|
| 173 |
"""
|
| 174 |
n_samples = self.chunk_length * sampling_rate
|
| 175 |
nb_max_frames = n_samples // self.hop_length
|
|
|
|
| 181 |
chunk = np.asarray(chunk, dtype=np.float32)
|
| 182 |
chunk_len = len(chunk)
|
| 183 |
|
| 184 |
+
# Pad or truncate
|
| 185 |
if chunk_len < n_samples:
|
| 186 |
padded = np.full(n_samples, self.padding_value, dtype=np.float32)
|
| 187 |
padded[:chunk_len] = chunk
|
|
|
|
| 191 |
|
| 192 |
padded_waveforms.append(padded)
|
| 193 |
|
| 194 |
+
# Attention mask (sample-level -> frame-level)
|
| 195 |
sample_mask = np.zeros(n_samples, dtype=np.int32)
|
| 196 |
sample_mask[:chunk_len] = 1
|
| 197 |
frame_mask = sample_mask[:: self.hop_length]
|
|
|
|
| 198 |
if len(frame_mask) > nb_max_frames:
|
| 199 |
frame_mask = frame_mask[:nb_max_frames]
|
| 200 |
elif len(frame_mask) < nb_max_frames:
|
|
|
|
| 210 |
"attention_mask": attention_mask,
|
| 211 |
}
|
| 212 |
|
| 213 |
+
def _get_feature_lengths(self, audio_masks: torch.Tensor) -> torch.Tensor:
|
| 214 |
+
"""Compute feature lengths after conv downsampling.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
|
| 216 |
Args:
|
| 217 |
+
audio_masks: Attention mask of shape (batch, nb_max_frames).
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
|
| 219 |
Returns:
|
| 220 |
+
Feature lengths tensor of shape (batch,).
|
|
|
|
| 221 |
"""
|
| 222 |
+
return (audio_masks.sum(-1) - 1) // 2 + 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
+
def _get_attention_mask(self, audio_masks: torch.Tensor) -> torch.Tensor:
|
| 225 |
+
"""Generate attention mask for the audio encoder.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 226 |
|
| 227 |
+
Creates a causal-style mask where padded positions are filled with -inf.
|
| 228 |
|
| 229 |
+
Args:
|
| 230 |
+
audio_masks: Attention mask of shape (batch, nb_max_frames).
|
|
|
|
|
|
|
|
|
|
| 231 |
|
| 232 |
+
Returns:
|
| 233 |
+
Attention mask of shape (batch, 1, max_seq_len, max_seq_len).
|
| 234 |
+
"""
|
|
|
|
|
|
|
| 235 |
feature_lengths = self._get_feature_lengths(audio_masks=audio_masks)
|
| 236 |
+
max_seq_len = (self.nb_max_frames - 2) // 2 + 1
|
| 237 |
padding_mask = torch.arange(max_seq_len) >= feature_lengths.unsqueeze(1)
|
| 238 |
+
attention_mask = padding_mask[:, None, None, :].expand(padding_mask.shape[0], 1, max_seq_len, max_seq_len)
|
| 239 |
attention_mask = attention_mask.masked_fill(attention_mask, float("-inf"))
|
| 240 |
return attention_mask
|
| 241 |
|
|
|
|
| 245 |
sampling_rate: Optional[int] = None,
|
| 246 |
chunk_length: Optional[int] = None,
|
| 247 |
) -> dict:
|
| 248 |
+
"""Preprocess audio clips for continuous audio features.
|
| 249 |
|
| 250 |
+
Splits each audio clip into chunks of chunk_length seconds, extracts
|
| 251 |
+
mel-spectrogram features, and computes token counts from attention masks.
|
| 252 |
|
| 253 |
Args:
|
| 254 |
+
audio_clips: List of audio clips, each a 1D numpy array (mono, float32).
|
| 255 |
+
sampling_rate: Audio sampling rate. Defaults to self.sampling_rate.
|
| 256 |
+
chunk_length: Chunk duration in seconds. Defaults to self.chunk_length.
|
|
|
|
| 257 |
|
| 258 |
Returns:
|
| 259 |
+
Dictionary with:
|
| 260 |
+
- "audio_values": Tensor of shape (num_total_chunks, feature_size, nb_max_frames).
|
| 261 |
+
- "audio_masks": Tensor of shape (num_total_chunks, nb_max_frames).
|
| 262 |
+
- "audio_attention_mask": Tensor of shape (num_total_chunks, max_seq_len, max_seq_len).
|
| 263 |
+
- "num_audio_tokens": Tensor of shape (N,) with per-clip continuous token counts.
|
| 264 |
"""
|
| 265 |
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 266 |
chunk_length = chunk_length if chunk_length is not None else self.chunk_length
|
| 267 |
|
| 268 |
if len(audio_clips) == 0:
|
|
|
|
|
|
|
| 269 |
max_seq_len = (self.nb_max_frames - 2) // 2 + 1
|
|
|
|
| 270 |
return {
|
| 271 |
+
"audio_values": torch.zeros(0, self.feature_size, self.nb_max_frames),
|
| 272 |
+
"audio_masks": torch.zeros(0, self.nb_max_frames),
|
| 273 |
+
"audio_attention_mask": torch.zeros(0, max_seq_len, max_seq_len),
|
| 274 |
"num_audio_tokens": torch.tensor([], dtype=torch.long),
|
| 275 |
}
|
| 276 |
|
|
|
|
| 285 |
|
| 286 |
_audio_value = result["input_features"]
|
| 287 |
_audio_mask = result["attention_mask"]
|
| 288 |
+
_num_audio_token = 0
|
| 289 |
+
for _mask in _audio_mask:
|
| 290 |
+
_input_length = (_mask.shape[-1] - 1) // 2 + 1
|
| 291 |
+
_num_audio_token += (_input_length - 2) // 2 + 1
|
| 292 |
|
| 293 |
_audio_values.append(torch.Tensor(_audio_value))
|
| 294 |
_audio_masks.append(torch.Tensor(_audio_mask))
|
| 295 |
+
_num_audio_tokens.append(_num_audio_token)
|
| 296 |
|
| 297 |
_audio_values = torch.cat(_audio_values, dim=0)
|
| 298 |
_audio_masks = torch.cat(_audio_masks, dim=0)
|
| 299 |
+
_audio_attention_mask = self._get_attention_mask(audio_masks=_audio_masks)
|
| 300 |
+
|
|
|
|
|
|
|
| 301 |
return {
|
| 302 |
"audio_values": _audio_values,
|
| 303 |
"audio_masks": _audio_masks,
|
|
|
|
| 312 |
chunk_unit: Optional[int] = None,
|
| 313 |
min_chunk_size: Optional[int] = None,
|
| 314 |
) -> dict:
|
| 315 |
+
"""Preprocess audio clips for discrete audio tokens.
|
| 316 |
|
| 317 |
+
Validates each audio clip and computes the number of discrete tokens
|
| 318 |
+
based on conv layer downsampling. Returns padded waveform tensors.
|
|
|
|
| 319 |
|
| 320 |
Args:
|
| 321 |
+
audio_clips: List of audio clips, each a 1D numpy array (mono, float32).
|
| 322 |
+
sampling_rate: Audio sampling rate. Defaults to self.sampling_rate.
|
| 323 |
+
chunk_unit: Chunk duration in seconds for long audio. Defaults to self.chunk_unit.
|
| 324 |
+
min_chunk_size: Minimum audio length in samples. Defaults to self.min_chunk_size.
|
|
|
|
| 325 |
|
| 326 |
Returns:
|
| 327 |
+
Dictionary with:
|
| 328 |
+
- "discrete_audio_values": Tensor of shape (N, max_audio_len).
|
| 329 |
+
- "num_discrete_audio_tokens": Tensor of shape (N,) with per-clip discrete token counts.
|
| 330 |
"""
|
| 331 |
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 332 |
chunk_unit = chunk_unit if chunk_unit is not None else self.chunk_unit
|
|
|
|
| 389 |
min_chunk_size: Optional[int] = None,
|
| 390 |
**kwargs,
|
| 391 |
) -> BatchFeature:
|
| 392 |
+
"""Preprocess a list of audio clips.
|
| 393 |
|
| 394 |
+
Performs continuous audio processing on all clips. If use_discrete_audio_token
|
| 395 |
+
is enabled, discrete audio processing is also performed.
|
|
|
|
| 396 |
|
| 397 |
Args:
|
| 398 |
+
audios: List of audio clips, each a 1D numpy array.
|
| 399 |
+
sampling_rate: Audio sampling rate. Defaults to self.sampling_rate.
|
| 400 |
+
chunk_length: Chunk duration in seconds for continuous processing.
|
| 401 |
+
Defaults to self.chunk_length.
|
| 402 |
+
chunk_unit: Chunk duration in seconds for discrete processing.
|
| 403 |
+
Defaults to self.chunk_unit.
|
| 404 |
+
min_chunk_size: Minimum audio length in samples for discrete processing.
|
| 405 |
+
Defaults to self.min_chunk_size.
|
| 406 |
|
| 407 |
Returns:
|
| 408 |
BatchFeature with:
|
| 409 |
+
- audio_values: Tensor of shape (num_total_chunks, feature_size, nb_max_frames).
|
| 410 |
+
- audio_masks: Tensor of shape (num_total_chunks, nb_max_frames).
|
| 411 |
+
- audio_attention_mask: Tensor of shape (num_total_chunks, max_seq_len, max_seq_len).
|
| 412 |
+
- num_audio_tokens: Tensor of shape (N,) with per-clip continuous token counts.
|
| 413 |
+
- discrete_audio_values (optional): Tensor of shape (N, max_audio_len).
|
| 414 |
+
- num_discrete_audio_tokens (optional): Tensor of shape (N,) with per-clip discrete token counts.
|
| 415 |
"""
|
| 416 |
continuous_result = self._preprocess_continuous_audio(
|
| 417 |
audios,
|
|
|
|
| 437 |
data["num_discrete_audio_tokens"] = discrete_result["num_discrete_audio_tokens"]
|
| 438 |
|
| 439 |
return BatchFeature(data=data, tensor_type="pt")
|
| 440 |
+
|
| 441 |
+
def get_num_audio_tokens(
|
| 442 |
+
self,
|
| 443 |
+
audio_masks: torch.Tensor,
|
| 444 |
+
discrete_audio_values: Optional[torch.Tensor] = None,
|
| 445 |
+
include_boundary_tokens: bool = False,
|
| 446 |
+
chunk_unit: Optional[int] = None,
|
| 447 |
+
sampling_rate: Optional[int] = None,
|
| 448 |
+
return_tuple: Optional[bool] = None,
|
| 449 |
+
) -> int:
|
| 450 |
+
"""Compute the number of audio tokens for the given input.
|
| 451 |
+
|
| 452 |
+
Args:
|
| 453 |
+
audio_masks: Attention mask for continuous audio. Shape (N,) or (num_chunks, N).
|
| 454 |
+
discrete_audio_values: Discrete audio waveform. None to skip discrete computation.
|
| 455 |
+
include_boundary_tokens: Whether to include start/end boundary tokens.
|
| 456 |
+
chunk_unit: Chunk duration in seconds for discrete processing.
|
| 457 |
+
Defaults to self.chunk_unit.
|
| 458 |
+
sampling_rate: Audio sampling rate. Defaults to self.sampling_rate.
|
| 459 |
+
return_tuple: If True, return (continuous, discrete) tuple.
|
| 460 |
+
Otherwise return the sum.
|
| 461 |
+
|
| 462 |
+
Returns:
|
| 463 |
+
Token count as int, or (continuous, discrete) tuple if return_tuple is True.
|
| 464 |
+
"""
|
| 465 |
+
chunk_unit = chunk_unit if chunk_unit is not None else self.chunk_unit
|
| 466 |
+
sampling_rate = sampling_rate if sampling_rate is not None else self.sampling_rate
|
| 467 |
+
|
| 468 |
+
def _compute_continuous_tokens(audio_mask: torch.Tensor) -> int:
|
| 469 |
+
input_length = (audio_mask.shape[-1] - 1) // 2 + 1
|
| 470 |
+
return (input_length - 2) // 2 + 1
|
| 471 |
+
|
| 472 |
+
num_continuous_tokens, num_discrete_tokens = 0, 0
|
| 473 |
+
if len(audio_masks.shape) == 1:
|
| 474 |
+
num_continuous_tokens = _compute_continuous_tokens(audio_masks)
|
| 475 |
+
else:
|
| 476 |
+
num_continuous_tokens = sum(_compute_continuous_tokens(m) for m in audio_masks)
|
| 477 |
+
if include_boundary_tokens:
|
| 478 |
+
num_continuous_tokens += 2
|
| 479 |
+
|
| 480 |
+
if self.use_discrete_audio_token and discrete_audio_values is not None:
|
| 481 |
+
audio_length = len(discrete_audio_values)
|
| 482 |
+
chunk_size = chunk_unit * sampling_rate
|
| 483 |
+
for _start in range(0, audio_length, chunk_size):
|
| 484 |
+
_end = min(_start + chunk_size, audio_length)
|
| 485 |
+
_chunked_length = _end - _start
|
| 486 |
+
mel_len = _chunked_length // 160
|
| 487 |
+
after_conv1 = (mel_len + 2 * 1 - 1 * (3 - 1) - 1) // 2 + 1
|
| 488 |
+
code_len = (after_conv1 + 2 * 1 - 1 * (3 - 1) - 1) // 2 + 1
|
| 489 |
+
num_discrete_tokens += code_len
|
| 490 |
+
if include_boundary_tokens:
|
| 491 |
+
num_discrete_tokens += 2
|
| 492 |
+
|
| 493 |
+
if return_tuple:
|
| 494 |
+
return (num_continuous_tokens, num_discrete_tokens)
|
| 495 |
+
else:
|
| 496 |
+
return num_continuous_tokens + num_discrete_tokens
|
chat_template.jinja
CHANGED
|
@@ -78,7 +78,7 @@
|
|
| 78 |
{%- set image_id = 'image_%02d' % ns_img.count %}
|
| 79 |
{%- set ns_img.count = ns_img.count + 1 %}
|
| 80 |
{{- '<|mime_start|>{"id": "' + image_id + '", "type": "image/jpeg", "filename": "' + content.get('filename', "a.jpg") + '"}<|mime_end|>\n' }}
|
| 81 |
-
{{- '<|discrete_image_start|><|DISCRETE_IMAGE_PAD|><|discrete_image_end|>'}}
|
| 82 |
{{- '<|image_start|><|IMAGE_PAD|><|image_end|>' }}
|
| 83 |
{%- elif content['type'] == 'video' or 'video' in content or 'video_url' in content %}
|
| 84 |
{%- set video_id = 'video_%02d' % ns_vid.count %}
|
|
@@ -91,7 +91,7 @@
|
|
| 91 |
{%- set ns_aud.count = ns_aud.count + 1 %}
|
| 92 |
{{- '<|mime_start|>{"id": "' + audio_id + '", "type": "audio/wav", "filename": "' + content.get('filename', "a.wav") + '"}<|mime_end|>\n' }}
|
| 93 |
{{- '<|audio_aux_start|>다음 중 audio_duration은 오디오 길이 정보입니다. 참고하여 답변하세요. {"audio_duration": ' + (content.get('audio_duration') | tojson if content.get('audio_duration') else '<|audio_duration|>') + '}<|audio_aux_end|>\n'}}
|
| 94 |
-
{{- '<|discrete_audio_start|><|DISCRETE_AUDIO_PAD|><|discrete_audio_end|>'}}
|
| 95 |
{{- '<|audio_start|><|AUDIO_PAD|><|audio_end|>'}}
|
| 96 |
{%- elif content['type'] == 'text' %}
|
| 97 |
{{- content['text'] }}
|
|
|
|
| 78 |
{%- set image_id = 'image_%02d' % ns_img.count %}
|
| 79 |
{%- set ns_img.count = ns_img.count + 1 %}
|
| 80 |
{{- '<|mime_start|>{"id": "' + image_id + '", "type": "image/jpeg", "filename": "' + content.get('filename', "a.jpg") + '"}<|mime_end|>\n' }}
|
| 81 |
+
{{- '<|discrete_image_start|><|DISCRETE_IMAGE_PAD|><|discrete_image_end|>\n'}}
|
| 82 |
{{- '<|image_start|><|IMAGE_PAD|><|image_end|>' }}
|
| 83 |
{%- elif content['type'] == 'video' or 'video' in content or 'video_url' in content %}
|
| 84 |
{%- set video_id = 'video_%02d' % ns_vid.count %}
|
|
|
|
| 91 |
{%- set ns_aud.count = ns_aud.count + 1 %}
|
| 92 |
{{- '<|mime_start|>{"id": "' + audio_id + '", "type": "audio/wav", "filename": "' + content.get('filename', "a.wav") + '"}<|mime_end|>\n' }}
|
| 93 |
{{- '<|audio_aux_start|>다음 중 audio_duration은 오디오 길이 정보입니다. 참고하여 답변하세요. {"audio_duration": ' + (content.get('audio_duration') | tojson if content.get('audio_duration') else '<|audio_duration|>') + '}<|audio_aux_end|>\n'}}
|
| 94 |
+
{{- '<|discrete_audio_start|><|DISCRETE_AUDIO_PAD|><|discrete_audio_end|>\n'}}
|
| 95 |
{{- '<|audio_start|><|AUDIO_PAD|><|audio_end|>'}}
|
| 96 |
{%- elif content['type'] == 'text' %}
|
| 97 |
{{- content['text'] }}
|
config.json
CHANGED
|
@@ -4,89 +4,28 @@
|
|
| 4 |
"HyperCLOVAXOmniForCausalLM"
|
| 5 |
],
|
| 6 |
"audio_config": {
|
| 7 |
-
"_name_or_path": "",
|
| 8 |
"activation_dropout": 0.0,
|
| 9 |
"activation_function": "gelu",
|
| 10 |
-
"add_cross_attention": false,
|
| 11 |
"architectures": [
|
| 12 |
"Qwen2AudioEncoder"
|
| 13 |
],
|
| 14 |
"attention_dropout": 0.0,
|
| 15 |
-
"bad_words_ids": null,
|
| 16 |
-
"begin_suppress_tokens": null,
|
| 17 |
-
"bos_token_id": null,
|
| 18 |
-
"chunk_size_feed_forward": 0,
|
| 19 |
-
"cross_attention_hidden_size": null,
|
| 20 |
"d_model": 1280,
|
| 21 |
-
"decoder_start_token_id": null,
|
| 22 |
-
"diversity_penalty": 0.0,
|
| 23 |
-
"do_sample": false,
|
| 24 |
"dropout": 0.0,
|
| 25 |
-
"early_stopping": false,
|
| 26 |
"encoder_attention_heads": 20,
|
| 27 |
"encoder_ffn_dim": 5120,
|
| 28 |
"encoder_layerdrop": 0.0,
|
| 29 |
"encoder_layers": 32,
|
| 30 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 31 |
-
"eos_token_id": null,
|
| 32 |
-
"exponential_decay_length_penalty": null,
|
| 33 |
-
"finetuning_task": null,
|
| 34 |
-
"forced_bos_token_id": null,
|
| 35 |
-
"forced_eos_token_id": null,
|
| 36 |
-
"id2label": {
|
| 37 |
-
"0": "LABEL_0",
|
| 38 |
-
"1": "LABEL_1"
|
| 39 |
-
},
|
| 40 |
"init_std": 0.02,
|
| 41 |
"initializer_range": 0.02,
|
| 42 |
-
"is_decoder": false,
|
| 43 |
-
"is_encoder_decoder": false,
|
| 44 |
-
"label2id": {
|
| 45 |
-
"LABEL_0": 0,
|
| 46 |
-
"LABEL_1": 1
|
| 47 |
-
},
|
| 48 |
-
"length_penalty": 1.0,
|
| 49 |
-
"max_length": 20,
|
| 50 |
"max_source_positions": 1500,
|
| 51 |
-
"min_length": 0,
|
| 52 |
"model_type": "qwen2_audio_encoder",
|
| 53 |
-
"no_repeat_ngram_size": 0,
|
| 54 |
-
"num_beam_groups": 1,
|
| 55 |
-
"num_beams": 1,
|
| 56 |
"num_hidden_layers": 32,
|
| 57 |
"num_mel_bins": 128,
|
| 58 |
-
"
|
| 59 |
-
"output_attentions": false,
|
| 60 |
-
"output_hidden_states": false,
|
| 61 |
-
"output_scores": false,
|
| 62 |
-
"pad_token_id": null,
|
| 63 |
-
"prefix": null,
|
| 64 |
-
"problem_type": null,
|
| 65 |
-
"pruned_heads": {},
|
| 66 |
-
"remove_invalid_values": false,
|
| 67 |
-
"repetition_penalty": 1.0,
|
| 68 |
-
"return_dict": true,
|
| 69 |
-
"return_dict_in_generate": false,
|
| 70 |
-
"scale_embedding": false,
|
| 71 |
-
"sep_token_id": null,
|
| 72 |
-
"suppress_tokens": null,
|
| 73 |
-
"task_specific_params": null,
|
| 74 |
-
"temperature": 1.0,
|
| 75 |
-
"tf_legacy_loss": false,
|
| 76 |
-
"tie_encoder_decoder": false,
|
| 77 |
-
"tie_word_embeddings": true,
|
| 78 |
-
"tokenizer_class": null,
|
| 79 |
-
"top_k": 50,
|
| 80 |
-
"top_p": 1.0,
|
| 81 |
-
"torch_dtype": "float32",
|
| 82 |
-
"torchscript": false,
|
| 83 |
-
"typical_p": 1.0,
|
| 84 |
-
"use_bfloat16": false
|
| 85 |
},
|
| 86 |
"audio_end_token_id": 128257,
|
| 87 |
-
"audio_model_name_or_path": null,
|
| 88 |
"audio_projector_type": "mlp",
|
| 89 |
-
"audio_start_id": 128071,
|
| 90 |
"audio_start_token_id": 128256,
|
| 91 |
"audio_token_id": 128071,
|
| 92 |
"auto_map": {
|
|
@@ -95,8 +34,6 @@
|
|
| 95 |
"AutoModelForSequenceClassification": "modeling_hyperclovax_omni.HyperCLOVAXOmniForSequenceClassification"
|
| 96 |
},
|
| 97 |
"discrete_audio_config": {
|
| 98 |
-
"_name_or_path": "",
|
| 99 |
-
"add_cross_attention": false,
|
| 100 |
"architectures": [
|
| 101 |
"CosyvoiceEncoder"
|
| 102 |
],
|
|
@@ -104,34 +41,6 @@
|
|
| 104 |
"AutoConfig": "configuration_cosyvoice2.CosyVoice2Config",
|
| 105 |
"AutoModel": "modeling_cosyvoice2.CosyVoice2Model"
|
| 106 |
},
|
| 107 |
-
"bad_words_ids": null,
|
| 108 |
-
"begin_suppress_tokens": null,
|
| 109 |
-
"bos_token_id": null,
|
| 110 |
-
"chunk_size_feed_forward": 0,
|
| 111 |
-
"cross_attention_hidden_size": null,
|
| 112 |
-
"decoder_start_token_id": null,
|
| 113 |
-
"diversity_penalty": 0.0,
|
| 114 |
-
"do_sample": false,
|
| 115 |
-
"early_stopping": false,
|
| 116 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 117 |
-
"eos_token_id": null,
|
| 118 |
-
"exponential_decay_length_penalty": null,
|
| 119 |
-
"finetuning_task": null,
|
| 120 |
-
"forced_bos_token_id": null,
|
| 121 |
-
"forced_eos_token_id": null,
|
| 122 |
-
"id2label": {
|
| 123 |
-
"0": "LABEL_0",
|
| 124 |
-
"1": "LABEL_1"
|
| 125 |
-
},
|
| 126 |
-
"is_decoder": false,
|
| 127 |
-
"is_encoder_decoder": false,
|
| 128 |
-
"label2id": {
|
| 129 |
-
"LABEL_0": 0,
|
| 130 |
-
"LABEL_1": 1
|
| 131 |
-
},
|
| 132 |
-
"length_penalty": 1.0,
|
| 133 |
-
"max_length": 20,
|
| 134 |
-
"min_length": 0,
|
| 135 |
"model_type": "cosyvoice2",
|
| 136 |
"n_audio_ctx": 1500,
|
| 137 |
"n_audio_head": 20,
|
|
@@ -139,39 +48,9 @@
|
|
| 139 |
"n_audio_state": 1280,
|
| 140 |
"n_codebook_size": 6561,
|
| 141 |
"n_mels": 128,
|
| 142 |
-
"no_repeat_ngram_size": 0,
|
| 143 |
-
"num_beam_groups": 1,
|
| 144 |
-
"num_beams": 1,
|
| 145 |
-
"num_return_sequences": 1,
|
| 146 |
-
"output_attentions": false,
|
| 147 |
-
"output_hidden_states": false,
|
| 148 |
-
"output_scores": false,
|
| 149 |
-
"pad_token_id": null,
|
| 150 |
-
"prefix": null,
|
| 151 |
-
"problem_type": null,
|
| 152 |
-
"pruned_heads": {},
|
| 153 |
-
"remove_invalid_values": false,
|
| 154 |
-
"repetition_penalty": 1.0,
|
| 155 |
-
"return_dict": true,
|
| 156 |
-
"return_dict_in_generate": false,
|
| 157 |
-
"sep_token_id": null,
|
| 158 |
-
"suppress_tokens": null,
|
| 159 |
-
"task_specific_params": null,
|
| 160 |
-
"temperature": 1.0,
|
| 161 |
-
"tf_legacy_loss": false,
|
| 162 |
-
"tie_encoder_decoder": false,
|
| 163 |
-
"tie_word_embeddings": true,
|
| 164 |
-
"tokenizer_class": null,
|
| 165 |
-
"top_k": 50,
|
| 166 |
-
"top_p": 1.0,
|
| 167 |
-
"torch_dtype": "float32",
|
| 168 |
-
"torchscript": false,
|
| 169 |
-
"typical_p": 1.0,
|
| 170 |
-
"use_bfloat16": false,
|
| 171 |
"use_sdpa": true
|
| 172 |
},
|
| 173 |
"discrete_audio_end_token_id": 128073,
|
| 174 |
-
"discrete_audio_model_name_or_path": null,
|
| 175 |
"discrete_audio_start_token_id": 128072,
|
| 176 |
"discrete_audio_token_id": 128074,
|
| 177 |
"discrete_audio_unit_0_id": 128606,
|
|
@@ -180,9 +59,6 @@
|
|
| 180 |
"discrete_image_token_id": 128069,
|
| 181 |
"discrete_image_unit_0_id": 135168,
|
| 182 |
"discrete_vision_config": {
|
| 183 |
-
"_name_or_path": "",
|
| 184 |
-
|
| 185 |
-
"add_cross_attention": false,
|
| 186 |
"architectures": [
|
| 187 |
"TextAlignedTokenizer"
|
| 188 |
],
|
|
@@ -190,9 +66,6 @@
|
|
| 190 |
"AutoConfig": "configuration_tatok.TATokConfig",
|
| 191 |
"AutoModel": "modeling_tatok.TATokModel"
|
| 192 |
},
|
| 193 |
-
"bad_words_ids": null,
|
| 194 |
-
"begin_suppress_tokens": null,
|
| 195 |
-
"bos_token_id": null,
|
| 196 |
"bottleneck": {
|
| 197 |
"args": {
|
| 198 |
"bottleneck_dim": 1536,
|
|
@@ -217,85 +90,21 @@
|
|
| 217 |
"name": "bottleneck"
|
| 218 |
},
|
| 219 |
"bottleneck_token_num": 729,
|
| 220 |
-
"chunk_size_feed_forward": 0,
|
| 221 |
-
"ckpt_path": "google/siglip2-so400m-patch14-384",
|
| 222 |
-
"cross_attention_hidden_size": null,
|
| 223 |
"decoder_depth": 3,
|
| 224 |
-
"decoder_start_token_id": null,
|
| 225 |
-
"diversity_penalty": 0.0,
|
| 226 |
-
"do_sample": false,
|
| 227 |
-
"early_stopping": false,
|
| 228 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 229 |
-
"eos_token_id": null,
|
| 230 |
-
"exponential_decay_length_penalty": null,
|
| 231 |
-
"finetuning_task": null,
|
| 232 |
-
"forced_bos_token_id": null,
|
| 233 |
-
"forced_eos_token_id": null,
|
| 234 |
-
"id2label": {
|
| 235 |
-
"0": "LABEL_0",
|
| 236 |
-
"1": "LABEL_1"
|
| 237 |
-
},
|
| 238 |
"input_size": 384,
|
| 239 |
"input_type": "indices",
|
| 240 |
-
"is_decoder": false,
|
| 241 |
-
"is_encoder_decoder": false,
|
| 242 |
-
"label2id": {
|
| 243 |
-
"LABEL_0": 0,
|
| 244 |
-
"LABEL_1": 1
|
| 245 |
-
},
|
| 246 |
-
"length_penalty": 1.0,
|
| 247 |
-
"max_length": 20,
|
| 248 |
-
"min_length": 0,
|
| 249 |
"model_type": "tatok",
|
| 250 |
-
"no_repeat_ngram_size": 0,
|
| 251 |
-
"num_beam_groups": 1,
|
| 252 |
-
"num_beams": 1,
|
| 253 |
-
"num_return_sequences": 1,
|
| 254 |
-
"output_attentions": false,
|
| 255 |
-
"output_hidden_states": false,
|
| 256 |
-
"output_scores": false,
|
| 257 |
-
"pad_token_id": null,
|
| 258 |
"pool_scale": 1,
|
| 259 |
-
"prefix": null,
|
| 260 |
-
"problem_type": null,
|
| 261 |
-
"pruned_heads": {},
|
| 262 |
"rand_scale": true,
|
| 263 |
-
"remove_invalid_values": false,
|
| 264 |
-
"repetition_penalty": 1.0,
|
| 265 |
-
"return_dict": true,
|
| 266 |
-
"return_dict_in_generate": false,
|
| 267 |
"select_layer_id": -2,
|
| 268 |
-
"
|
| 269 |
-
"suppress_tokens": null,
|
| 270 |
-
"task_specific_params": null,
|
| 271 |
-
"teacher": "google/siglip2-so400m-patch14-384",
|
| 272 |
-
"temperature": 1.0,
|
| 273 |
-
"tf_legacy_loss": false,
|
| 274 |
-
"tie_encoder_decoder": false,
|
| 275 |
-
"tie_word_embeddings": true,
|
| 276 |
-
"tokenizer_class": null,
|
| 277 |
-
"top_k": 50,
|
| 278 |
-
"top_p": 1.0,
|
| 279 |
-
"torch_dtype": "float32",
|
| 280 |
-
"torchscript": false,
|
| 281 |
-
"typical_p": 1.0,
|
| 282 |
-
"use_bfloat16": false
|
| 283 |
},
|
| 284 |
-
"discrete_vision_model_name_or_path": null,
|
| 285 |
-
"end_token_id": 128001,
|
| 286 |
"eos_token_id": 128001,
|
| 287 |
-
"freeze_audio_projector": true,
|
| 288 |
-
"freeze_before_sampler": false,
|
| 289 |
-
"freeze_decoder": false,
|
| 290 |
-
"freeze_encoder": true,
|
| 291 |
-
"freeze_mm_projector": false,
|
| 292 |
-
"freeze_video_audio_compressor": false,
|
| 293 |
"hidden_size": 4096,
|
| 294 |
"ignore_index": -100,
|
| 295 |
"image_end_token_id": 128058,
|
| 296 |
"image_start_token_id": 128059,
|
| 297 |
"image_token_id": 128062,
|
| 298 |
-
"img_start_id": 128062,
|
| 299 |
"is_safetensor_save": true,
|
| 300 |
"max_num_grids": -1,
|
| 301 |
"mm_projector_type": "linear",
|
|
@@ -305,95 +114,35 @@
|
|
| 305 |
"possible_resolutions": [],
|
| 306 |
"proj_pos_emb": true,
|
| 307 |
"proj_prenorm": false,
|
| 308 |
-
"q_former_model_name_or_path": null,
|
| 309 |
-
"skip_ve_mlp_infer": true,
|
| 310 |
"text_config": {
|
| 311 |
-
"_name_or_path": "",
|
| 312 |
-
"add_cross_attention": false,
|
| 313 |
"architectures": [
|
| 314 |
"LlamaForCausalLM"
|
| 315 |
],
|
| 316 |
"attention_bias": false,
|
| 317 |
"attention_dropout": 0.0,
|
| 318 |
-
"bad_words_ids": null,
|
| 319 |
-
"begin_suppress_tokens": null,
|
| 320 |
"bos_token_id": 128000,
|
| 321 |
-
"chunk_size_feed_forward": 0,
|
| 322 |
-
"cross_attention_hidden_size": null,
|
| 323 |
-
"decoder_start_token_id": null,
|
| 324 |
-
"diversity_penalty": 0.0,
|
| 325 |
-
"do_sample": false,
|
| 326 |
-
"early_stopping": false,
|
| 327 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 328 |
"eos_token_id": 128001,
|
| 329 |
-
"exponential_decay_length_penalty": null,
|
| 330 |
-
"finetuning_task": null,
|
| 331 |
-
"forced_bos_token_id": null,
|
| 332 |
-
"forced_eos_token_id": null,
|
| 333 |
"head_dim": 128,
|
| 334 |
"hidden_act": "silu",
|
| 335 |
"hidden_size": 4096,
|
| 336 |
-
"id2label": {
|
| 337 |
-
"0": "LABEL_0",
|
| 338 |
-
"1": "LABEL_1"
|
| 339 |
-
},
|
| 340 |
"initializer_range": 0.02,
|
| 341 |
"intermediate_size": 12288,
|
| 342 |
-
"is_decoder": false,
|
| 343 |
-
"is_encoder_decoder": false,
|
| 344 |
-
"label2id": {
|
| 345 |
-
"LABEL_0": 0,
|
| 346 |
-
"LABEL_1": 1
|
| 347 |
-
},
|
| 348 |
-
"length_penalty": 1.0,
|
| 349 |
"logits_scaling": 1.0,
|
| 350 |
-
"max_length": 20,
|
| 351 |
"max_position_embeddings": 8192,
|
| 352 |
-
"min_length": 0,
|
| 353 |
"mlp_bias": false,
|
| 354 |
"model_type": "llama",
|
| 355 |
-
"no_repeat_ngram_size": 0,
|
| 356 |
"num_attention_heads": 32,
|
| 357 |
-
"num_beam_groups": 1,
|
| 358 |
-
"num_beams": 1,
|
| 359 |
"num_hidden_layers": 36,
|
| 360 |
"num_key_value_heads": 8,
|
| 361 |
-
"num_return_sequences": 1,
|
| 362 |
-
"output_attentions": false,
|
| 363 |
-
"output_hidden_states": false,
|
| 364 |
-
"output_scores": false,
|
| 365 |
-
"pad_token_id": null,
|
| 366 |
-
"prefix": null,
|
| 367 |
"pretraining_tp": 1,
|
| 368 |
-
"problem_type": null,
|
| 369 |
-
"pruned_heads": {},
|
| 370 |
-
"remove_invalid_values": false,
|
| 371 |
-
"repetition_penalty": 1.0,
|
| 372 |
-
"return_dict": true,
|
| 373 |
-
"return_dict_in_generate": false,
|
| 374 |
"rms_norm_eps": 1e-06,
|
| 375 |
"rope_scaling": null,
|
| 376 |
"rope_theta": 5000000,
|
| 377 |
-
"sep_token_id": null,
|
| 378 |
-
"suppress_tokens": null,
|
| 379 |
-
"task_specific_params": null,
|
| 380 |
-
"temperature": 1.0,
|
| 381 |
-
"tf_legacy_loss": false,
|
| 382 |
-
"tie_encoder_decoder": false,
|
| 383 |
"tie_word_embeddings": false,
|
| 384 |
-
"tokenizer_class": null,
|
| 385 |
-
"top_k": 50,
|
| 386 |
-
"top_p": 1.0,
|
| 387 |
-
"torch_dtype": "float32",
|
| 388 |
-
"torchscript": false,
|
| 389 |
-
"typical_p": 1.0,
|
| 390 |
-
"use_bfloat16": false,
|
| 391 |
"use_cache": true,
|
| 392 |
"vocab_size": 200704
|
| 393 |
},
|
| 394 |
-
"text_model_name_or_path": "",
|
| 395 |
"torch_dtype": "float32",
|
| 396 |
-
"transformers_version": "4.52.4",
|
| 397 |
"unpad": false,
|
| 398 |
"use_1x1_grid": false,
|
| 399 |
"use_components": {
|
|
@@ -403,112 +152,34 @@
|
|
| 403 |
"use_discrete_audio": true,
|
| 404 |
"use_discrete_vision": true
|
| 405 |
},
|
| 406 |
-
"
|
| 407 |
"video_audio_compressor_config": {
|
| 408 |
-
"_name_or_path": "",
|
| 409 |
-
"add_cross_attention": false,
|
| 410 |
"architectures": null,
|
| 411 |
"auto_map": {
|
| 412 |
"AutoConfig": "configuration_mambamia.MambaMiaVideoAudioCompressorConfig",
|
| 413 |
"AutoModel": "modeling_mambamia.MambaMiaVideoAudioCompressor"
|
| 414 |
},
|
| 415 |
-
"bad_words_ids": null,
|
| 416 |
-
"begin_suppress_tokens": null,
|
| 417 |
-
"bos_token_id": null,
|
| 418 |
"chunk_size": 25,
|
| 419 |
-
"chunk_size_feed_forward": 0,
|
| 420 |
-
"cross_attention_hidden_size": null,
|
| 421 |
-
"decoder_start_token_id": null,
|
| 422 |
-
"diversity_penalty": 0.0,
|
| 423 |
-
"do_sample": false,
|
| 424 |
-
"early_stopping": false,
|
| 425 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 426 |
-
"eos_token_id": null,
|
| 427 |
-
"exponential_decay_length_penalty": null,
|
| 428 |
-
"finetuning_task": null,
|
| 429 |
-
"forced_bos_token_id": null,
|
| 430 |
-
"forced_eos_token_id": null,
|
| 431 |
"hidden_size": 3072,
|
| 432 |
-
"id2label": {
|
| 433 |
-
"0": "LABEL_0",
|
| 434 |
-
"1": "LABEL_1"
|
| 435 |
-
},
|
| 436 |
"input_size": 4096,
|
| 437 |
-
"is_decoder": false,
|
| 438 |
-
"is_encoder_decoder": false,
|
| 439 |
-
"label2id": {
|
| 440 |
-
"LABEL_0": 0,
|
| 441 |
-
"LABEL_1": 1
|
| 442 |
-
},
|
| 443 |
-
"length_penalty": 1.0,
|
| 444 |
-
"max_length": 20,
|
| 445 |
-
"min_length": 0,
|
| 446 |
"model_type": "mambamia_videoaudio_compressor",
|
| 447 |
-
"no_repeat_ngram_size": 0,
|
| 448 |
-
"num_beam_groups": 1,
|
| 449 |
-
"num_beams": 1,
|
| 450 |
"num_hidden_layers": 1,
|
| 451 |
-
"
|
| 452 |
-
"output_attentions": false,
|
| 453 |
-
"output_hidden_states": false,
|
| 454 |
-
"output_scores": false,
|
| 455 |
-
"output_size": 4096,
|
| 456 |
-
"pad_token_id": null,
|
| 457 |
-
"prefix": null,
|
| 458 |
-
"problem_type": null,
|
| 459 |
-
"pruned_heads": {},
|
| 460 |
-
"remove_invalid_values": false,
|
| 461 |
-
"repetition_penalty": 1.0,
|
| 462 |
-
"return_dict": true,
|
| 463 |
-
"return_dict_in_generate": false,
|
| 464 |
-
"sep_token_id": null,
|
| 465 |
-
"suppress_tokens": null,
|
| 466 |
-
"task_specific_params": null,
|
| 467 |
-
"temperature": 1.0,
|
| 468 |
-
"tf_legacy_loss": false,
|
| 469 |
-
"tie_encoder_decoder": false,
|
| 470 |
-
"tie_word_embeddings": true,
|
| 471 |
-
"tokenizer_class": null,
|
| 472 |
-
"top_k": 50,
|
| 473 |
-
"top_p": 1.0,
|
| 474 |
-
"torch_dtype": null,
|
| 475 |
-
"torchscript": false,
|
| 476 |
-
"typical_p": 1.0,
|
| 477 |
-
"use_bfloat16": false
|
| 478 |
},
|
| 479 |
"video_audio_compressor_type": "mambamia",
|
| 480 |
-
"video_audio_start_id": 128070,
|
| 481 |
"video_audio_token_id": 128070,
|
| 482 |
"video_end_token_id": 128061,
|
| 483 |
"video_first_last_frames_slows": null,
|
| 484 |
"video_num_queries_fast": null,
|
| 485 |
"video_num_queries_slow": null,
|
| 486 |
-
"video_start_id": 128063,
|
| 487 |
"video_start_token_id": 128060,
|
| 488 |
"video_token_id": 128063,
|
| 489 |
"vision_config": {
|
| 490 |
-
"_name_or_path": "",
|
| 491 |
-
"add_cross_attention": false,
|
| 492 |
"anyres": false,
|
| 493 |
"architectures": [
|
| 494 |
"Qwen2_5_VisionTransformerPretrainedModel"
|
| 495 |
],
|
| 496 |
-
"bad_words_ids": null,
|
| 497 |
-
"begin_suppress_tokens": null,
|
| 498 |
-
"bos_token_id": null,
|
| 499 |
-
"chunk_size_feed_forward": 0,
|
| 500 |
-
"cross_attention_hidden_size": null,
|
| 501 |
-
"decoder_start_token_id": null,
|
| 502 |
"depth": 32,
|
| 503 |
-
"diversity_penalty": 0.0,
|
| 504 |
-
"do_sample": false,
|
| 505 |
-
"early_stopping": false,
|
| 506 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 507 |
-
"eos_token_id": null,
|
| 508 |
-
"exponential_decay_length_penalty": null,
|
| 509 |
-
"finetuning_task": null,
|
| 510 |
-
"forced_bos_token_id": null,
|
| 511 |
-
"forced_eos_token_id": null,
|
| 512 |
"fullatt_block_indexes": [
|
| 513 |
7,
|
| 514 |
15,
|
|
@@ -517,63 +188,20 @@
|
|
| 517 |
],
|
| 518 |
"hidden_act": "silu",
|
| 519 |
"hidden_size": 1280,
|
| 520 |
-
"id2label": {
|
| 521 |
-
"0": "LABEL_0",
|
| 522 |
-
"1": "LABEL_1"
|
| 523 |
-
},
|
| 524 |
"in_channels": 3,
|
| 525 |
"in_chans": 3,
|
| 526 |
"initializer_range": 0.02,
|
| 527 |
"intermediate_size": 3456,
|
| 528 |
-
"is_decoder": false,
|
| 529 |
-
"is_encoder_decoder": false,
|
| 530 |
-
"label2id": {
|
| 531 |
-
"LABEL_0": 0,
|
| 532 |
-
"LABEL_1": 1
|
| 533 |
-
},
|
| 534 |
-
"length_penalty": 1.0,
|
| 535 |
-
"max_length": 20,
|
| 536 |
"max_num_grids": -1,
|
| 537 |
-
"min_length": 0,
|
| 538 |
"model_type": "qwen2_5_vl_visual",
|
| 539 |
-
"no_repeat_ngram_size": 0,
|
| 540 |
-
"num_beam_groups": 1,
|
| 541 |
-
"num_beams": 1,
|
| 542 |
"num_heads": 16,
|
| 543 |
-
"num_return_sequences": 1,
|
| 544 |
"out_hidden_size": 5120,
|
| 545 |
-
"output_attentions": false,
|
| 546 |
-
"output_hidden_states": false,
|
| 547 |
-
"output_scores": false,
|
| 548 |
-
"pad_token_id": null,
|
| 549 |
"patch_size": 14,
|
| 550 |
-
"prefix": null,
|
| 551 |
-
"problem_type": null,
|
| 552 |
-
"pruned_heads": {},
|
| 553 |
-
"remove_invalid_values": false,
|
| 554 |
-
"repetition_penalty": 1.0,
|
| 555 |
-
"return_dict": true,
|
| 556 |
-
"return_dict_in_generate": false,
|
| 557 |
-
"sep_token_id": null,
|
| 558 |
"spatial_merge_size": 2,
|
| 559 |
"spatial_patch_size": 14,
|
| 560 |
-
"suppress_tokens": null,
|
| 561 |
-
"task_specific_params": null,
|
| 562 |
-
"temperature": 1.0,
|
| 563 |
"temporal_patch_size": 2,
|
| 564 |
-
"tf_legacy_loss": false,
|
| 565 |
-
"tie_encoder_decoder": false,
|
| 566 |
-
"tie_word_embeddings": true,
|
| 567 |
-
"tokenizer_class": null,
|
| 568 |
"tokens_per_second": 2,
|
| 569 |
-
"top_k": 50,
|
| 570 |
-
"top_p": 1.0,
|
| 571 |
-
"torch_dtype": "float32",
|
| 572 |
-
"torchscript": false,
|
| 573 |
-
"typical_p": 1.0,
|
| 574 |
-
"use_bfloat16": false,
|
| 575 |
"window_size": 112
|
| 576 |
},
|
| 577 |
-
"vision_input_chunk_size": null
|
| 578 |
-
"vision_model_name_or_path": null
|
| 579 |
}
|
|
|
|
| 4 |
"HyperCLOVAXOmniForCausalLM"
|
| 5 |
],
|
| 6 |
"audio_config": {
|
|
|
|
| 7 |
"activation_dropout": 0.0,
|
| 8 |
"activation_function": "gelu",
|
|
|
|
| 9 |
"architectures": [
|
| 10 |
"Qwen2AudioEncoder"
|
| 11 |
],
|
| 12 |
"attention_dropout": 0.0,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
"d_model": 1280,
|
|
|
|
|
|
|
|
|
|
| 14 |
"dropout": 0.0,
|
|
|
|
| 15 |
"encoder_attention_heads": 20,
|
| 16 |
"encoder_ffn_dim": 5120,
|
| 17 |
"encoder_layerdrop": 0.0,
|
| 18 |
"encoder_layers": 32,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
"init_std": 0.02,
|
| 20 |
"initializer_range": 0.02,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
"max_source_positions": 1500,
|
|
|
|
| 22 |
"model_type": "qwen2_audio_encoder",
|
|
|
|
|
|
|
|
|
|
| 23 |
"num_hidden_layers": 32,
|
| 24 |
"num_mel_bins": 128,
|
| 25 |
+
"scale_embedding": false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
},
|
| 27 |
"audio_end_token_id": 128257,
|
|
|
|
| 28 |
"audio_projector_type": "mlp",
|
|
|
|
| 29 |
"audio_start_token_id": 128256,
|
| 30 |
"audio_token_id": 128071,
|
| 31 |
"auto_map": {
|
|
|
|
| 34 |
"AutoModelForSequenceClassification": "modeling_hyperclovax_omni.HyperCLOVAXOmniForSequenceClassification"
|
| 35 |
},
|
| 36 |
"discrete_audio_config": {
|
|
|
|
|
|
|
| 37 |
"architectures": [
|
| 38 |
"CosyvoiceEncoder"
|
| 39 |
],
|
|
|
|
| 41 |
"AutoConfig": "configuration_cosyvoice2.CosyVoice2Config",
|
| 42 |
"AutoModel": "modeling_cosyvoice2.CosyVoice2Model"
|
| 43 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
"model_type": "cosyvoice2",
|
| 45 |
"n_audio_ctx": 1500,
|
| 46 |
"n_audio_head": 20,
|
|
|
|
| 48 |
"n_audio_state": 1280,
|
| 49 |
"n_codebook_size": 6561,
|
| 50 |
"n_mels": 128,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
"use_sdpa": true
|
| 52 |
},
|
| 53 |
"discrete_audio_end_token_id": 128073,
|
|
|
|
| 54 |
"discrete_audio_start_token_id": 128072,
|
| 55 |
"discrete_audio_token_id": 128074,
|
| 56 |
"discrete_audio_unit_0_id": 128606,
|
|
|
|
| 59 |
"discrete_image_token_id": 128069,
|
| 60 |
"discrete_image_unit_0_id": 135168,
|
| 61 |
"discrete_vision_config": {
|
|
|
|
|
|
|
|
|
|
| 62 |
"architectures": [
|
| 63 |
"TextAlignedTokenizer"
|
| 64 |
],
|
|
|
|
| 66 |
"AutoConfig": "configuration_tatok.TATokConfig",
|
| 67 |
"AutoModel": "modeling_tatok.TATokModel"
|
| 68 |
},
|
|
|
|
|
|
|
|
|
|
| 69 |
"bottleneck": {
|
| 70 |
"args": {
|
| 71 |
"bottleneck_dim": 1536,
|
|
|
|
| 90 |
"name": "bottleneck"
|
| 91 |
},
|
| 92 |
"bottleneck_token_num": 729,
|
|
|
|
|
|
|
|
|
|
| 93 |
"decoder_depth": 3,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
"input_size": 384,
|
| 95 |
"input_type": "indices",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
"model_type": "tatok",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
"pool_scale": 1,
|
|
|
|
|
|
|
|
|
|
| 98 |
"rand_scale": true,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
"select_layer_id": -2,
|
| 100 |
+
"teacher": "google/siglip2-so400m-patch14-384"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
},
|
|
|
|
|
|
|
| 102 |
"eos_token_id": 128001,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
"hidden_size": 4096,
|
| 104 |
"ignore_index": -100,
|
| 105 |
"image_end_token_id": 128058,
|
| 106 |
"image_start_token_id": 128059,
|
| 107 |
"image_token_id": 128062,
|
|
|
|
| 108 |
"is_safetensor_save": true,
|
| 109 |
"max_num_grids": -1,
|
| 110 |
"mm_projector_type": "linear",
|
|
|
|
| 114 |
"possible_resolutions": [],
|
| 115 |
"proj_pos_emb": true,
|
| 116 |
"proj_prenorm": false,
|
|
|
|
|
|
|
| 117 |
"text_config": {
|
|
|
|
|
|
|
| 118 |
"architectures": [
|
| 119 |
"LlamaForCausalLM"
|
| 120 |
],
|
| 121 |
"attention_bias": false,
|
| 122 |
"attention_dropout": 0.0,
|
|
|
|
|
|
|
| 123 |
"bos_token_id": 128000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
"eos_token_id": 128001,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
"head_dim": 128,
|
| 126 |
"hidden_act": "silu",
|
| 127 |
"hidden_size": 4096,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 128 |
"initializer_range": 0.02,
|
| 129 |
"intermediate_size": 12288,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
"logits_scaling": 1.0,
|
|
|
|
| 131 |
"max_position_embeddings": 8192,
|
|
|
|
| 132 |
"mlp_bias": false,
|
| 133 |
"model_type": "llama",
|
|
|
|
| 134 |
"num_attention_heads": 32,
|
|
|
|
|
|
|
| 135 |
"num_hidden_layers": 36,
|
| 136 |
"num_key_value_heads": 8,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
"pretraining_tp": 1,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
"rms_norm_eps": 1e-06,
|
| 139 |
"rope_scaling": null,
|
| 140 |
"rope_theta": 5000000,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
"tie_word_embeddings": false,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
"use_cache": true,
|
| 143 |
"vocab_size": 200704
|
| 144 |
},
|
|
|
|
| 145 |
"torch_dtype": "float32",
|
|
|
|
| 146 |
"unpad": false,
|
| 147 |
"use_1x1_grid": false,
|
| 148 |
"use_components": {
|
|
|
|
| 152 |
"use_discrete_audio": true,
|
| 153 |
"use_discrete_vision": true
|
| 154 |
},
|
| 155 |
+
"vision_feature_layer": -2,
|
| 156 |
"video_audio_compressor_config": {
|
|
|
|
|
|
|
| 157 |
"architectures": null,
|
| 158 |
"auto_map": {
|
| 159 |
"AutoConfig": "configuration_mambamia.MambaMiaVideoAudioCompressorConfig",
|
| 160 |
"AutoModel": "modeling_mambamia.MambaMiaVideoAudioCompressor"
|
| 161 |
},
|
|
|
|
|
|
|
|
|
|
| 162 |
"chunk_size": 25,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 163 |
"hidden_size": 3072,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
"input_size": 4096,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 165 |
"model_type": "mambamia_videoaudio_compressor",
|
|
|
|
|
|
|
|
|
|
| 166 |
"num_hidden_layers": 1,
|
| 167 |
+
"output_size": 4096
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
},
|
| 169 |
"video_audio_compressor_type": "mambamia",
|
|
|
|
| 170 |
"video_audio_token_id": 128070,
|
| 171 |
"video_end_token_id": 128061,
|
| 172 |
"video_first_last_frames_slows": null,
|
| 173 |
"video_num_queries_fast": null,
|
| 174 |
"video_num_queries_slow": null,
|
|
|
|
| 175 |
"video_start_token_id": 128060,
|
| 176 |
"video_token_id": 128063,
|
| 177 |
"vision_config": {
|
|
|
|
|
|
|
| 178 |
"anyres": false,
|
| 179 |
"architectures": [
|
| 180 |
"Qwen2_5_VisionTransformerPretrainedModel"
|
| 181 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
"depth": 32,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
"fullatt_block_indexes": [
|
| 184 |
7,
|
| 185 |
15,
|
|
|
|
| 188 |
],
|
| 189 |
"hidden_act": "silu",
|
| 190 |
"hidden_size": 1280,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 191 |
"in_channels": 3,
|
| 192 |
"in_chans": 3,
|
| 193 |
"initializer_range": 0.02,
|
| 194 |
"intermediate_size": 3456,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
"max_num_grids": -1,
|
|
|
|
| 196 |
"model_type": "qwen2_5_vl_visual",
|
|
|
|
|
|
|
|
|
|
| 197 |
"num_heads": 16,
|
|
|
|
| 198 |
"out_hidden_size": 5120,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
"patch_size": 14,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
"spatial_merge_size": 2,
|
| 201 |
"spatial_patch_size": 14,
|
|
|
|
|
|
|
|
|
|
| 202 |
"temporal_patch_size": 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
"tokens_per_second": 2,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
"window_size": 112
|
| 205 |
},
|
| 206 |
+
"vision_input_chunk_size": null
|
|
|
|
| 207 |
}
|
configuration_cosyvoice2.py
CHANGED
|
@@ -1,107 +1,70 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from transformers.configuration_utils import PretrainedConfig
|
| 4 |
|
| 5 |
-
|
| 6 |
class CosyVoice2Config(PretrainedConfig):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
model_type = "cosyvoice2"
|
| 8 |
|
| 9 |
def __init__(
|
| 10 |
self,
|
| 11 |
-
n_mels=128,
|
| 12 |
-
n_audio_ctx=1500,
|
| 13 |
-
n_audio_state=1280,
|
| 14 |
-
n_audio_head=20,
|
| 15 |
-
n_audio_layer=6,
|
| 16 |
-
n_codebook_size=6561, # 3**8
|
| 17 |
-
use_sdpa=True,
|
| 18 |
-
model_name_or_path=None,
|
| 19 |
**kwargs,
|
| 20 |
):
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
kwargs_use_sdpa = kwargs.pop("use_sdpa", True)
|
| 30 |
-
kwargs_model_name_or_path = kwargs.pop("model_name_or_path", None)
|
| 31 |
-
|
| 32 |
-
# Apply precedence rules
|
| 33 |
-
self.n_mels = n_mels if n_mels != 128 else kwargs_n_mels
|
| 34 |
-
self.n_audio_ctx = n_audio_ctx if n_audio_ctx != 1500 else kwargs_n_audio_ctx
|
| 35 |
-
self.n_audio_state = n_audio_state if n_audio_state != 1280 else kwargs_n_audio_state
|
| 36 |
-
self.n_audio_head = n_audio_head if n_audio_head != 20 else kwargs_n_audio_head
|
| 37 |
-
self.n_audio_layer = n_audio_layer if n_audio_layer != 6 else kwargs_n_audio_layer
|
| 38 |
-
self.n_codebook_size = n_codebook_size if n_codebook_size != 6561 else kwargs_n_codebook_size
|
| 39 |
-
self.use_sdpa = use_sdpa if use_sdpa is not True else kwargs_use_sdpa
|
| 40 |
-
self.model_name_or_path = model_name_or_path if model_name_or_path is not None else kwargs_model_name_or_path
|
| 41 |
|
| 42 |
-
# Default values for standard transformers config attributes
|
| 43 |
-
# These will be merged with kwargs so they appear even when not in config.json
|
| 44 |
-
default_transformers_config = {
|
| 45 |
-
"_name_or_path": None,
|
| 46 |
-
"add_cross_attention": False,
|
| 47 |
-
"architectures": ["CosyvoiceEncoder"],
|
| 48 |
-
"bad_words_ids": None,
|
| 49 |
-
"begin_suppress_tokens": None,
|
| 50 |
-
"bos_token_id": None,
|
| 51 |
-
"chunk_size_feed_forward": 0,
|
| 52 |
-
"cross_attention_hidden_size": None,
|
| 53 |
-
"decoder_start_token_id": None,
|
| 54 |
-
"diversity_penalty": 0.0,
|
| 55 |
-
"do_sample": False,
|
| 56 |
-
"early_stopping": False,
|
| 57 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 58 |
-
"eos_token_id": None,
|
| 59 |
-
"exponential_decay_length_penalty": None,
|
| 60 |
-
"finetuning_task": None,
|
| 61 |
-
"forced_bos_token_id": None,
|
| 62 |
-
"forced_eos_token_id": None,
|
| 63 |
-
"id2label": {"0": "LABEL_0", "1": "LABEL_1"},
|
| 64 |
-
"is_decoder": False,
|
| 65 |
-
"is_encoder_decoder": False,
|
| 66 |
-
"label2id": {"LABEL_0": 0, "LABEL_1": 1},
|
| 67 |
-
"length_penalty": 1.0,
|
| 68 |
-
"max_length": 20,
|
| 69 |
-
"min_length": 0,
|
| 70 |
-
"no_repeat_ngram_size": 0,
|
| 71 |
-
"num_beam_groups": 1,
|
| 72 |
-
"num_beams": 1,
|
| 73 |
-
"num_return_sequences": 1,
|
| 74 |
-
"output_attentions": False,
|
| 75 |
-
"output_hidden_states": False,
|
| 76 |
-
"output_scores": False,
|
| 77 |
-
"pad_token_id": None,
|
| 78 |
-
"prefix": None,
|
| 79 |
-
"problem_type": None,
|
| 80 |
-
"pruned_heads": {},
|
| 81 |
-
"remove_invalid_values": False,
|
| 82 |
-
"repetition_penalty": 1.0,
|
| 83 |
-
"return_dict": True,
|
| 84 |
-
"return_dict_in_generate": False,
|
| 85 |
-
"sep_token_id": None,
|
| 86 |
-
"suppress_tokens": None,
|
| 87 |
-
"task_specific_params": None,
|
| 88 |
-
"temperature": 1.0,
|
| 89 |
-
"tf_legacy_loss": False,
|
| 90 |
-
"tie_encoder_decoder": False,
|
| 91 |
-
"tie_word_embeddings": True,
|
| 92 |
-
"tokenizer_class": None,
|
| 93 |
-
"top_k": 50,
|
| 94 |
-
"top_p": 1.0,
|
| 95 |
-
"torch_dtype": "float32",
|
| 96 |
-
"torchscript": False,
|
| 97 |
-
"typical_p": 1.0,
|
| 98 |
-
"use_bfloat16": False,
|
| 99 |
-
}
|
| 100 |
|
| 101 |
-
|
| 102 |
-
merged_kwargs = {**default_transformers_config, **kwargs}
|
| 103 |
|
| 104 |
-
# Pass merged kwargs to parent (these are standard transformers config attributes)
|
| 105 |
-
super().__init__(**merged_kwargs)
|
| 106 |
-
|
| 107 |
__all__ = ["CosyVoice2Config"]
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 NAVER Cloud Corp. and the HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""CosyVoice2 audio encoder configuration"""
|
| 16 |
+
|
| 17 |
+
from transformers import AutoConfig
|
| 18 |
from transformers.configuration_utils import PretrainedConfig
|
| 19 |
|
| 20 |
+
|
| 21 |
class CosyVoice2Config(PretrainedConfig):
|
| 22 |
+
r"""
|
| 23 |
+
This is the configuration class to store the configuration of a CosyVoice2 audio encoder model.
|
| 24 |
+
|
| 25 |
+
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 26 |
+
documentation from [`PretrainedConfig`] for more information.
|
| 27 |
+
|
| 28 |
+
Args:
|
| 29 |
+
n_mels (`int`, *optional*, defaults to 128):
|
| 30 |
+
Number of mel frequency bins for the input spectrogram.
|
| 31 |
+
n_audio_ctx (`int`, *optional*, defaults to 1500):
|
| 32 |
+
Maximum audio context length.
|
| 33 |
+
n_audio_state (`int`, *optional*, defaults to 1280):
|
| 34 |
+
Dimensionality of the encoder hidden states.
|
| 35 |
+
n_audio_head (`int`, *optional*, defaults to 20):
|
| 36 |
+
Number of attention heads in the encoder.
|
| 37 |
+
n_audio_layer (`int`, *optional*, defaults to 6):
|
| 38 |
+
Number of encoder layers.
|
| 39 |
+
n_codebook_size (`int`, *optional*, defaults to 6561):
|
| 40 |
+
Size of the codebook (3^8).
|
| 41 |
+
use_sdpa (`bool`, *optional*, defaults to `True`):
|
| 42 |
+
Whether to use Scaled Dot-Product Attention.
|
| 43 |
+
"""
|
| 44 |
+
|
| 45 |
model_type = "cosyvoice2"
|
| 46 |
|
| 47 |
def __init__(
|
| 48 |
self,
|
| 49 |
+
n_mels: int = 128,
|
| 50 |
+
n_audio_ctx: int = 1500,
|
| 51 |
+
n_audio_state: int = 1280,
|
| 52 |
+
n_audio_head: int = 20,
|
| 53 |
+
n_audio_layer: int = 6,
|
| 54 |
+
n_codebook_size: int = 6561, # 3**8
|
| 55 |
+
use_sdpa: bool = True,
|
|
|
|
| 56 |
**kwargs,
|
| 57 |
):
|
| 58 |
+
super().__init__(**kwargs)
|
| 59 |
+
self.n_mels = n_mels
|
| 60 |
+
self.n_audio_ctx = n_audio_ctx
|
| 61 |
+
self.n_audio_state = n_audio_state
|
| 62 |
+
self.n_audio_head = n_audio_head
|
| 63 |
+
self.n_audio_layer = n_audio_layer
|
| 64 |
+
self.n_codebook_size = n_codebook_size
|
| 65 |
+
self.use_sdpa = use_sdpa
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
AutoConfig.register("cosyvoice2", CosyVoice2Config)
|
|
|
|
| 69 |
|
|
|
|
|
|
|
|
|
|
| 70 |
__all__ = ["CosyVoice2Config"]
|
configuration_hyperclovax.py
CHANGED
|
@@ -1,10 +1,5 @@
|
|
| 1 |
# coding=utf-8
|
| 2 |
-
# Copyright
|
| 3 |
-
#
|
| 4 |
-
# This code is based on EleutherAI's GPT-NeoX library and the GPT-NeoX
|
| 5 |
-
# and OPT implementations in this library. It has been modified from its
|
| 6 |
-
# original forms to accommodate minor architectural differences compared
|
| 7 |
-
# to GPT-NeoX and OPT used by the Meta AI team that trained the model.
|
| 8 |
#
|
| 9 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 10 |
# you may not use this file except in compliance with the License.
|
|
@@ -17,27 +12,26 @@
|
|
| 17 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 18 |
# See the License for the specific language governing permissions and
|
| 19 |
# limitations under the License.
|
| 20 |
-
"""
|
|
|
|
|
|
|
| 21 |
|
| 22 |
-
|
| 23 |
-
from transformers import AutoConfig, AutoModel, AutoModelForCausalLM
|
| 24 |
from transformers.configuration_utils import PretrainedConfig
|
| 25 |
|
| 26 |
|
| 27 |
class HyperCLOVAXConfig(PretrainedConfig):
|
| 28 |
r"""
|
| 29 |
-
This is the configuration class to store the configuration of a [`
|
| 30 |
-
model according to the specified arguments, defining the model architecture.
|
| 31 |
-
defaults will yield a similar configuration to that of the LLaMA-7B.
|
| 32 |
|
| 33 |
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 34 |
documentation from [`PretrainedConfig`] for more information.
|
| 35 |
|
| 36 |
-
|
| 37 |
Args:
|
| 38 |
vocab_size (`int`, *optional*, defaults to 32000):
|
| 39 |
-
Vocabulary size of the
|
| 40 |
-
`inputs_ids` passed when calling [`
|
| 41 |
hidden_size (`int`, *optional*, defaults to 4096):
|
| 42 |
Dimension of the hidden representations.
|
| 43 |
intermediate_size (`int`, *optional*, defaults to 11008):
|
|
@@ -57,8 +51,7 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 57 |
hidden_act (`str` or `function`, *optional*, defaults to `"silu"`):
|
| 58 |
The non-linear activation function (function or string) in the decoder.
|
| 59 |
max_position_embeddings (`int`, *optional*, defaults to 2048):
|
| 60 |
-
The maximum sequence length that this model might ever be used with.
|
| 61 |
-
Llama 2 up to 4096, CodeLlama up to 16384.
|
| 62 |
initializer_range (`float`, *optional*, defaults to 0.02):
|
| 63 |
The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
|
| 64 |
rms_norm_eps (`float`, *optional*, defaults to 1e-06):
|
|
@@ -78,7 +71,7 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 78 |
understand more about it. This value is necessary to ensure exact reproducibility of the pretraining
|
| 79 |
results. Please refer to [this issue](https://github.com/pytorch/pytorch/issues/76232).
|
| 80 |
tie_word_embeddings (`bool`, *optional*, defaults to `False`):
|
| 81 |
-
Whether to tie weight embeddings
|
| 82 |
rope_theta (`float`, *optional*, defaults to 10000.0):
|
| 83 |
The base period of the RoPE embeddings.
|
| 84 |
rope_scaling (`Dict`, *optional*):
|
|
@@ -125,19 +118,23 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 125 |
mlp_bias (`bool`, *optional*, defaults to `False`):
|
| 126 |
Whether to use a bias in up_proj, down_proj and gate_proj layers in the MLP layers.
|
| 127 |
head_dim (`int`, *optional*):
|
| 128 |
-
The attention head dimension. If None, it will default to hidden_size // num_heads
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
|
| 130 |
```python
|
| 131 |
-
>>> from
|
| 132 |
|
| 133 |
-
>>> # Initializing a
|
| 134 |
-
>>> configuration =
|
| 135 |
-
|
| 136 |
-
>>> # Initializing a model from the llama-7b style configuration
|
| 137 |
-
>>> model = LlamaModel(configuration)
|
| 138 |
-
|
| 139 |
-
>>> # Accessing the model configuration
|
| 140 |
-
>>> configuration = model.config
|
| 141 |
```"""
|
| 142 |
|
| 143 |
model_type = "hyperclovax"
|
|
@@ -145,40 +142,42 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 145 |
|
| 146 |
def __init__(
|
| 147 |
self,
|
| 148 |
-
vocab_size=32000,
|
| 149 |
-
hidden_size=4096,
|
| 150 |
-
intermediate_size=11008,
|
| 151 |
-
num_hidden_layers=32,
|
| 152 |
-
num_attention_heads=32,
|
| 153 |
-
num_key_value_heads=None,
|
| 154 |
-
hidden_act="silu",
|
| 155 |
-
max_position_embeddings=2048,
|
| 156 |
-
initializer_range=0.02,
|
| 157 |
-
rms_norm_eps=1e-6,
|
| 158 |
-
use_cache=True,
|
| 159 |
-
pad_token_id=None,
|
| 160 |
-
bos_token_id=1,
|
| 161 |
-
eos_token_id=2,
|
| 162 |
-
pretraining_tp=1,
|
| 163 |
-
tie_word_embeddings=False,
|
| 164 |
-
rope_theta=10000.0,
|
| 165 |
-
rope_scaling=None,
|
| 166 |
-
attention_bias=False,
|
| 167 |
-
attention_dropout=0.0,
|
| 168 |
-
mlp_bias=False,
|
| 169 |
-
head_dim=None,
|
| 170 |
-
embedding_multiplier=1.0,
|
| 171 |
-
logits_scaling=1.0,
|
| 172 |
-
attention_multiplier=1.0,
|
| 173 |
-
residual_multiplier=1.0,
|
| 174 |
-
use_post_norm=False,
|
| 175 |
-
auto_map={
|
| 176 |
-
"AutoConfig": "configuration_hyperclovax.HyperCLOVAXConfig",
|
| 177 |
-
"AutoModel": "modeling_hyperclovax.HyperCLOVAXModel",
|
| 178 |
-
"AutoModelForCausalLM": "modeling_hyperclovax.HyperCLOVAXForCausalLM",
|
| 179 |
-
},
|
| 180 |
**kwargs,
|
| 181 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 182 |
self.vocab_size = vocab_size
|
| 183 |
self.max_position_embeddings = max_position_embeddings
|
| 184 |
self.hidden_size = hidden_size
|
|
@@ -202,11 +201,9 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 202 |
self.attention_dropout = attention_dropout
|
| 203 |
self.mlp_bias = mlp_bias
|
| 204 |
self.head_dim = head_dim if head_dim is not None else self.hidden_size // self.num_attention_heads
|
| 205 |
-
#
|
| 206 |
-
# BC: if there is a 'type' field, copy it it to 'rope_type'.
|
| 207 |
if self.rope_scaling is not None and "type" in self.rope_scaling:
|
| 208 |
self.rope_scaling["rope_type"] = self.rope_scaling["type"]
|
| 209 |
-
# rope_config_validation(self)
|
| 210 |
|
| 211 |
# mup
|
| 212 |
self.embedding_multiplier = embedding_multiplier
|
|
@@ -217,13 +214,7 @@ class HyperCLOVAXConfig(PretrainedConfig):
|
|
| 217 |
# post-norm (dual-norm)
|
| 218 |
self.use_post_norm = use_post_norm
|
| 219 |
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
eos_token_id=eos_token_id,
|
| 224 |
-
tie_word_embeddings=tie_word_embeddings,
|
| 225 |
-
auto_map=auto_map,
|
| 226 |
-
**kwargs,
|
| 227 |
-
)
|
| 228 |
-
|
| 229 |
__all__ = ["HyperCLOVAXConfig"]
|
|
|
|
| 1 |
# coding=utf-8
|
| 2 |
+
# Copyright 2024 NAVER Cloud Corp. and the HuggingFace Inc. team. All rights reserved.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
#
|
| 4 |
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
# you may not use this file except in compliance with the License.
|
|
|
|
| 12 |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
# See the License for the specific language governing permissions and
|
| 14 |
# limitations under the License.
|
| 15 |
+
"""HyperCLOVAX model configuration"""
|
| 16 |
+
|
| 17 |
+
from typing import Optional
|
| 18 |
|
| 19 |
+
from transformers import AutoConfig
|
|
|
|
| 20 |
from transformers.configuration_utils import PretrainedConfig
|
| 21 |
|
| 22 |
|
| 23 |
class HyperCLOVAXConfig(PretrainedConfig):
|
| 24 |
r"""
|
| 25 |
+
This is the configuration class to store the configuration of a [`HyperCLOVAXModel`]. It is used to instantiate a
|
| 26 |
+
HyperCLOVAX model according to the specified arguments, defining the model architecture.
|
|
|
|
| 27 |
|
| 28 |
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 29 |
documentation from [`PretrainedConfig`] for more information.
|
| 30 |
|
|
|
|
| 31 |
Args:
|
| 32 |
vocab_size (`int`, *optional*, defaults to 32000):
|
| 33 |
+
Vocabulary size of the HyperCLOVAX model. Defines the number of different tokens that can be represented
|
| 34 |
+
by the `inputs_ids` passed when calling [`HyperCLOVAXModel`].
|
| 35 |
hidden_size (`int`, *optional*, defaults to 4096):
|
| 36 |
Dimension of the hidden representations.
|
| 37 |
intermediate_size (`int`, *optional*, defaults to 11008):
|
|
|
|
| 51 |
hidden_act (`str` or `function`, *optional*, defaults to `"silu"`):
|
| 52 |
The non-linear activation function (function or string) in the decoder.
|
| 53 |
max_position_embeddings (`int`, *optional*, defaults to 2048):
|
| 54 |
+
The maximum sequence length that this model might ever be used with.
|
|
|
|
| 55 |
initializer_range (`float`, *optional*, defaults to 0.02):
|
| 56 |
The standard deviation of the truncated_normal_initializer for initializing all weight matrices.
|
| 57 |
rms_norm_eps (`float`, *optional*, defaults to 1e-06):
|
|
|
|
| 71 |
understand more about it. This value is necessary to ensure exact reproducibility of the pretraining
|
| 72 |
results. Please refer to [this issue](https://github.com/pytorch/pytorch/issues/76232).
|
| 73 |
tie_word_embeddings (`bool`, *optional*, defaults to `False`):
|
| 74 |
+
Whether to tie weight embeddings.
|
| 75 |
rope_theta (`float`, *optional*, defaults to 10000.0):
|
| 76 |
The base period of the RoPE embeddings.
|
| 77 |
rope_scaling (`Dict`, *optional*):
|
|
|
|
| 118 |
mlp_bias (`bool`, *optional*, defaults to `False`):
|
| 119 |
Whether to use a bias in up_proj, down_proj and gate_proj layers in the MLP layers.
|
| 120 |
head_dim (`int`, *optional*):
|
| 121 |
+
The attention head dimension. If None, it will default to hidden_size // num_heads.
|
| 122 |
+
embedding_multiplier (`float`, *optional*, defaults to 1.0):
|
| 123 |
+
Multiplier for the embedding layer output, used for muP (maximal update parametrization).
|
| 124 |
+
logits_scaling (`float`, *optional*, defaults to 1.0):
|
| 125 |
+
Scaling factor for the logits, used for muP.
|
| 126 |
+
attention_multiplier (`float`, *optional*, defaults to 1.0):
|
| 127 |
+
Multiplier for the attention scores, used for muP.
|
| 128 |
+
residual_multiplier (`float`, *optional*, defaults to 1.0):
|
| 129 |
+
Multiplier for the residual connections, used for muP.
|
| 130 |
+
use_post_norm (`bool`, *optional*, defaults to `False`):
|
| 131 |
+
Whether to apply post-normalization (dual-norm) in addition to pre-normalization.
|
| 132 |
|
| 133 |
```python
|
| 134 |
+
>>> from configuration_hyperclovax import HyperCLOVAXConfig
|
| 135 |
|
| 136 |
+
>>> # Initializing a HyperCLOVAX configuration
|
| 137 |
+
>>> configuration = HyperCLOVAXConfig()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
```"""
|
| 139 |
|
| 140 |
model_type = "hyperclovax"
|
|
|
|
| 142 |
|
| 143 |
def __init__(
|
| 144 |
self,
|
| 145 |
+
vocab_size: int = 32000,
|
| 146 |
+
hidden_size: int = 4096,
|
| 147 |
+
intermediate_size: int = 11008,
|
| 148 |
+
num_hidden_layers: int = 32,
|
| 149 |
+
num_attention_heads: int = 32,
|
| 150 |
+
num_key_value_heads: Optional[int] = None,
|
| 151 |
+
hidden_act: str = "silu",
|
| 152 |
+
max_position_embeddings: int = 2048,
|
| 153 |
+
initializer_range: float = 0.02,
|
| 154 |
+
rms_norm_eps: float = 1e-6,
|
| 155 |
+
use_cache: bool = True,
|
| 156 |
+
pad_token_id: Optional[int] = None,
|
| 157 |
+
bos_token_id: int = 1,
|
| 158 |
+
eos_token_id: int = 2,
|
| 159 |
+
pretraining_tp: int = 1,
|
| 160 |
+
tie_word_embeddings: bool = False,
|
| 161 |
+
rope_theta: float = 10000.0,
|
| 162 |
+
rope_scaling: Optional[dict] = None,
|
| 163 |
+
attention_bias: bool = False,
|
| 164 |
+
attention_dropout: float = 0.0,
|
| 165 |
+
mlp_bias: bool = False,
|
| 166 |
+
head_dim: Optional[int] = None,
|
| 167 |
+
embedding_multiplier: float = 1.0,
|
| 168 |
+
logits_scaling: float = 1.0,
|
| 169 |
+
attention_multiplier: float = 1.0,
|
| 170 |
+
residual_multiplier: float = 1.0,
|
| 171 |
+
use_post_norm: bool = False,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 172 |
**kwargs,
|
| 173 |
):
|
| 174 |
+
super().__init__(
|
| 175 |
+
pad_token_id=pad_token_id,
|
| 176 |
+
bos_token_id=bos_token_id,
|
| 177 |
+
eos_token_id=eos_token_id,
|
| 178 |
+
tie_word_embeddings=tie_word_embeddings,
|
| 179 |
+
**kwargs,
|
| 180 |
+
)
|
| 181 |
self.vocab_size = vocab_size
|
| 182 |
self.max_position_embeddings = max_position_embeddings
|
| 183 |
self.hidden_size = hidden_size
|
|
|
|
| 201 |
self.attention_dropout = attention_dropout
|
| 202 |
self.mlp_bias = mlp_bias
|
| 203 |
self.head_dim = head_dim if head_dim is not None else self.hidden_size // self.num_attention_heads
|
| 204 |
+
# BC: if there is a 'type' field, copy it to 'rope_type'.
|
|
|
|
| 205 |
if self.rope_scaling is not None and "type" in self.rope_scaling:
|
| 206 |
self.rope_scaling["rope_type"] = self.rope_scaling["type"]
|
|
|
|
| 207 |
|
| 208 |
# mup
|
| 209 |
self.embedding_multiplier = embedding_multiplier
|
|
|
|
| 214 |
# post-norm (dual-norm)
|
| 215 |
self.use_post_norm = use_post_norm
|
| 216 |
|
| 217 |
+
|
| 218 |
+
AutoConfig.register("hyperclovax", HyperCLOVAXConfig)
|
| 219 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
__all__ = ["HyperCLOVAXConfig"]
|
configuration_hyperclovax_omni.py
CHANGED
|
@@ -1,35 +1,134 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from transformers import (
|
| 4 |
-
AutoConfig,
|
| 5 |
-
CLIPVisionConfig,
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
| 8 |
)
|
| 9 |
-
from transformers.models.qwen2_5_vl.
|
| 10 |
|
| 11 |
from .configuration_cosyvoice2 import CosyVoice2Config
|
| 12 |
from .configuration_hyperclovax import HyperCLOVAXConfig
|
| 13 |
from .configuration_mambamia import MambaMiaVideoAudioCompressorConfig
|
| 14 |
from .configuration_tatok import TATokConfig
|
| 15 |
|
|
|
|
| 16 |
class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
model_type = "hyperclovax_omni"
|
| 18 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 19 |
|
| 20 |
-
|
| 21 |
-
"text_config",
|
| 22 |
-
"vision_config",
|
| 23 |
-
"audio_config",
|
| 24 |
-
"discrete_vision_config",
|
| 25 |
-
"discrete_audio_config",
|
| 26 |
-
"video_audio_compressor_config",
|
| 27 |
-
|
| 28 |
|
| 29 |
@classmethod
|
| 30 |
-
def from_pretrained(cls, pretrained_model_name_or_path, **kwargs):
|
| 31 |
config = super().from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 32 |
-
|
|
|
|
|
|
|
| 33 |
sub_config = getattr(config, attr, None)
|
| 34 |
if sub_config is not None and hasattr(sub_config, "_name_or_path"):
|
| 35 |
sub_config._name_or_path = config._name_or_path
|
|
@@ -37,56 +136,35 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 37 |
|
| 38 |
def __init__(
|
| 39 |
self,
|
| 40 |
-
text_config=None,
|
| 41 |
-
vision_config=None,
|
| 42 |
-
discrete_vision_config=None,
|
| 43 |
-
audio_config=None,
|
| 44 |
-
discrete_audio_config=None,
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
freeze_decoder=False,
|
| 66 |
-
freeze_mm_projector=False,
|
| 67 |
-
freeze_audio_projector=False,
|
| 68 |
-
freeze_video_audio_compressor=False,
|
| 69 |
-
anyres=False,
|
| 70 |
-
unpad=False,
|
| 71 |
-
max_num_grids=-1,
|
| 72 |
-
num_queries_vis_abstractor=-1,
|
| 73 |
-
video_num_queries_fast=None,
|
| 74 |
-
video_num_queries_slow=None,
|
| 75 |
-
video_first_last_frames_slows=None,
|
| 76 |
-
video_max_num_frames=None,
|
| 77 |
-
ignore_index=-100,
|
| 78 |
-
proj_pos_emb=True,
|
| 79 |
-
proj_prenorm=False,
|
| 80 |
-
use_1x1_grid=False,
|
| 81 |
-
possible_resolutions=[],
|
| 82 |
**kwargs,
|
| 83 |
):
|
|
|
|
| 84 |
# text_config
|
| 85 |
-
if (
|
| 86 |
-
text_config is None
|
| 87 |
-
and text_model_name_or_path is not None
|
| 88 |
-
):
|
| 89 |
-
text_config = AutoConfig.from_pretrained(text_model_name_or_path, trust_remote_code=True)
|
| 90 |
if isinstance(text_config, dict):
|
| 91 |
if text_config["model_type"] == "hyperclovax":
|
| 92 |
text_config = HyperCLOVAXConfig(**text_config)
|
|
@@ -94,13 +172,13 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 94 |
text_config = LlamaConfig(**text_config)
|
| 95 |
else:
|
| 96 |
raise ValueError(f'Invalid text_config type: {text_config["model_type"]}')
|
| 97 |
-
if text_config is not None:
|
| 98 |
-
self.hidden_size = text_config.hidden_size
|
|
|
|
|
|
|
| 99 |
self.text_config = text_config
|
| 100 |
-
|
| 101 |
# audio_config
|
| 102 |
-
if audio_config is None and audio_model_name_or_path is not None:
|
| 103 |
-
audio_config = AutoConfig.from_pretrained(audio_model_name_or_path)
|
| 104 |
if isinstance(audio_config, dict):
|
| 105 |
if audio_config["model_type"] == "qwen2_audio_encoder":
|
| 106 |
audio_config = Qwen2AudioEncoderConfig(**audio_config)
|
|
@@ -109,26 +187,13 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 109 |
else:
|
| 110 |
raise ValueError(f'Invalid audio_config type: {audio_config["model_type"]}')
|
| 111 |
self.audio_config = audio_config
|
| 112 |
-
|
| 113 |
# discrete_audio_config
|
| 114 |
-
if discrete_audio_config
|
| 115 |
-
discrete_audio_config = {
|
| 116 |
-
"model_type": "cosyvoice2",
|
| 117 |
-
"model_name_or_path": discrete_audio_model_name_or_path,
|
| 118 |
-
}
|
| 119 |
-
if (
|
| 120 |
-
isinstance(CosyVoice2Config, type)
|
| 121 |
-
and isinstance(discrete_audio_config, dict)
|
| 122 |
-
):
|
| 123 |
discrete_audio_config = CosyVoice2Config.from_dict(discrete_audio_config)
|
| 124 |
self.discrete_audio_config = discrete_audio_config
|
| 125 |
-
|
| 126 |
# vision_config
|
| 127 |
-
if vision_config is None and vision_model_name_or_path is not None:
|
| 128 |
-
vision_config = AutoConfig.from_pretrained(
|
| 129 |
-
vision_model_name_or_path,
|
| 130 |
-
trust_remote_code=True,
|
| 131 |
-
)
|
| 132 |
if isinstance(vision_config, dict):
|
| 133 |
if vision_config["model_type"] == "clip_vision_model":
|
| 134 |
vision_config = CLIPVisionConfig(**vision_config)
|
|
@@ -139,16 +204,8 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 139 |
else:
|
| 140 |
raise ValueError(f'Invalid vision_config type: {vision_config["model_type"]}')
|
| 141 |
self.vision_config = vision_config
|
| 142 |
-
|
| 143 |
# discrete_vision_config
|
| 144 |
-
if (
|
| 145 |
-
discrete_vision_config is None
|
| 146 |
-
and discrete_vision_model_name_or_path is not None
|
| 147 |
-
):
|
| 148 |
-
discrete_vision_config = {
|
| 149 |
-
"model_type": "tatok",
|
| 150 |
-
"model_name_or_path": discrete_vision_model_name_or_path,
|
| 151 |
-
}
|
| 152 |
if isinstance(discrete_vision_config, dict):
|
| 153 |
discrete_vision_config = TATokConfig.from_dict(discrete_vision_config)
|
| 154 |
self.discrete_vision_config = discrete_vision_config
|
|
@@ -159,21 +216,10 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 159 |
self.video_audio_compressor_config = video_audio_compressor_config
|
| 160 |
|
| 161 |
# add VLM configs
|
| 162 |
-
self.text_model_name_or_path = text_model_name_or_path
|
| 163 |
-
self.vision_model_name_or_path = vision_model_name_or_path
|
| 164 |
-
self.discrete_vision_model_name_or_path = discrete_vision_model_name_or_path
|
| 165 |
-
self.audio_model_name_or_path = audio_model_name_or_path
|
| 166 |
-
self.discrete_audio_model_name_or_path = discrete_audio_model_name_or_path
|
| 167 |
-
self.q_former_model_name_or_path = q_former_model_name_or_path
|
| 168 |
self.mm_projector_type = mm_projector_type
|
| 169 |
self.audio_projector_type = audio_projector_type
|
| 170 |
self.video_audio_compressor_type = video_audio_compressor_type
|
| 171 |
-
self.
|
| 172 |
-
self.freeze_encoder = freeze_encoder
|
| 173 |
-
self.freeze_decoder = freeze_decoder
|
| 174 |
-
self.freeze_mm_projector = freeze_mm_projector
|
| 175 |
-
self.freeze_audio_projector = freeze_audio_projector
|
| 176 |
-
self.freeze_video_audio_compressor = freeze_video_audio_compressor
|
| 177 |
self.anyres = anyres
|
| 178 |
self.unpad = unpad
|
| 179 |
self.max_num_grids = max_num_grids
|
|
@@ -183,39 +229,20 @@ class HyperCLOVAXOmniConfig(PretrainedConfig):
|
|
| 183 |
self.video_first_last_frames_slows = video_first_last_frames_slows
|
| 184 |
self.video_max_num_frames = video_max_num_frames
|
| 185 |
|
| 186 |
-
self.img_start_id = img_start_id
|
| 187 |
-
self.image_token_id = img_start_id
|
| 188 |
-
|
| 189 |
-
self.discrete_image_start_id = discrete_image_start_id
|
| 190 |
-
self.discrete_image_token_id = discrete_image_start_id
|
| 191 |
self.discrete_image_unit_0_id = discrete_image_unit_0_id
|
| 192 |
-
|
| 193 |
-
self.video_start_id = video_start_id
|
| 194 |
-
self.video_token_id = video_start_id
|
| 195 |
-
|
| 196 |
-
self.video_audio_start_id = video_audio_start_id
|
| 197 |
-
self.video_audio_token_id = video_audio_start_id
|
| 198 |
-
|
| 199 |
-
self.audio_start_id = audio_start_id
|
| 200 |
-
self.audio_token_id = audio_start_id
|
| 201 |
-
|
| 202 |
-
self.discrete_audio_start_id = discrete_audio_start_id
|
| 203 |
-
self.discrete_audio_token_id = discrete_audio_start_id
|
| 204 |
self.discrete_audio_unit_0_id = discrete_audio_unit_0_id
|
| 205 |
|
| 206 |
self.ignore_index = ignore_index
|
| 207 |
self.proj_pos_emb = proj_pos_emb
|
| 208 |
self.proj_prenorm = proj_prenorm
|
| 209 |
self.use_1x1_grid = use_1x1_grid
|
| 210 |
-
self.possible_resolutions = possible_resolutions
|
| 211 |
-
|
| 212 |
-
super().__init__(**kwargs)
|
| 213 |
-
|
| 214 |
# needed for HCXVisionForSequenceClassification
|
| 215 |
-
if self.text_config is not None:
|
| 216 |
self.pad_token_id = self.text_config.pad_token_id
|
| 217 |
-
|
| 218 |
-
from transformers.models.qwen2_5_vl.modeling_qwen2_5_vl import Qwen2_5_VLVisionConfig
|
| 219 |
|
| 220 |
|
| 221 |
-
|
|
|
|
|
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 NAVER Cloud Corp. and the HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""HyperCLOVAX-Omni multimodal model configuration"""
|
| 16 |
+
|
| 17 |
+
from typing import Dict, List, Optional, Union
|
| 18 |
+
|
| 19 |
from transformers import (
|
| 20 |
+
AutoConfig,
|
| 21 |
+
CLIPVisionConfig,
|
| 22 |
+
LlamaConfig,
|
| 23 |
+
PretrainedConfig,
|
| 24 |
+
Qwen2AudioEncoderConfig,
|
| 25 |
+
SiglipVisionConfig,
|
| 26 |
+
WhisperConfig,
|
| 27 |
)
|
| 28 |
+
from transformers.models.qwen2_5_vl.configuration_qwen2_5_vl import Qwen2_5_VLVisionConfig
|
| 29 |
|
| 30 |
from .configuration_cosyvoice2 import CosyVoice2Config
|
| 31 |
from .configuration_hyperclovax import HyperCLOVAXConfig
|
| 32 |
from .configuration_mambamia import MambaMiaVideoAudioCompressorConfig
|
| 33 |
from .configuration_tatok import TATokConfig
|
| 34 |
|
| 35 |
+
|
| 36 |
class HyperCLOVAXOmniConfig(PretrainedConfig):
|
| 37 |
+
r"""
|
| 38 |
+
This is the configuration class to store the configuration of a [`HyperCLOVAXOmniForCausalLM`]. It is used to
|
| 39 |
+
instantiate a HyperCLOVAX-Omni multimodal model according to the specified arguments, defining the model
|
| 40 |
+
architecture including text, vision, and audio components.
|
| 41 |
+
|
| 42 |
+
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 43 |
+
documentation from [`PretrainedConfig`] for more information.
|
| 44 |
+
|
| 45 |
+
Args:
|
| 46 |
+
text_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 47 |
+
Configuration for the text backbone model. Accepts a `HyperCLOVAXConfig` or `LlamaConfig`.
|
| 48 |
+
vision_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 49 |
+
Configuration for the continuous vision encoder (e.g., CLIP, SigLIP, Qwen2.5-VL).
|
| 50 |
+
discrete_vision_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 51 |
+
Configuration for the discrete vision tokenizer (TATok).
|
| 52 |
+
audio_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 53 |
+
Configuration for the continuous audio encoder (e.g., Qwen2AudioEncoder, Whisper).
|
| 54 |
+
discrete_audio_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 55 |
+
Configuration for the discrete audio encoder (CosyVoice2).
|
| 56 |
+
text_model_name_or_path (`str`, *optional*):
|
| 57 |
+
Path or identifier of a pretrained text model to load config from.
|
| 58 |
+
vision_model_name_or_path (`str`, *optional*):
|
| 59 |
+
Path or identifier of a pretrained vision model to load config from.
|
| 60 |
+
discrete_vision_model_name_or_path (`str`, *optional*):
|
| 61 |
+
Path or identifier of a pretrained discrete vision model to load config from.
|
| 62 |
+
audio_model_name_or_path (`str`, *optional*):
|
| 63 |
+
Path or identifier of a pretrained audio model to load config from.
|
| 64 |
+
discrete_audio_model_name_or_path (`str`, *optional*):
|
| 65 |
+
Path or identifier of a pretrained discrete audio model to load config from.
|
| 66 |
+
mm_projector_type (`str`, *optional*, defaults to `"mlp"`):
|
| 67 |
+
Type of the multimodal projector for vision features.
|
| 68 |
+
audio_projector_type (`str`, *optional*, defaults to `"mlp"`):
|
| 69 |
+
Type of the projector for audio features.
|
| 70 |
+
video_audio_compressor_type (`str`, *optional*):
|
| 71 |
+
Type of the video-audio compressor (e.g., `"mambamia"`).
|
| 72 |
+
video_audio_compressor_config (`dict` or [`PretrainedConfig`], *optional*):
|
| 73 |
+
Configuration for the video-audio compressor module.
|
| 74 |
+
vision_feature_layer (`int`, *optional*, defaults to -2):
|
| 75 |
+
Index of the vision encoder layer to extract features from.
|
| 76 |
+
discrete_image_unit_0_id (`int`, *optional*, defaults to 135166):
|
| 77 |
+
Token id for `<|vision00000|>`, the first discrete vision unit token.
|
| 78 |
+
discrete_audio_unit_0_id (`int`, *optional*, defaults to 128604):
|
| 79 |
+
Token id for `<|audio0000|>`, the first discrete audio unit token.
|
| 80 |
+
anyres (`bool`, *optional*, defaults to `False`):
|
| 81 |
+
Whether to use any-resolution image processing.
|
| 82 |
+
unpad (`bool`, *optional*, defaults to `False`):
|
| 83 |
+
Whether to remove padding from image features.
|
| 84 |
+
max_num_grids (`int`, *optional*, defaults to -1):
|
| 85 |
+
Maximum number of grids for any-resolution processing. -1 means no limit.
|
| 86 |
+
num_queries_vis_abstractor (`int`, *optional*, defaults to -1):
|
| 87 |
+
Number of query tokens for the visual abstractor. -1 means disabled.
|
| 88 |
+
video_num_queries_fast (`int`, *optional*):
|
| 89 |
+
Number of query tokens for fast video frames.
|
| 90 |
+
video_num_queries_slow (`int`, *optional*):
|
| 91 |
+
Number of query tokens for slow video frames.
|
| 92 |
+
video_first_last_frames_slows (`int`, *optional*):
|
| 93 |
+
Number of first/last frames to process as slow frames.
|
| 94 |
+
video_max_num_frames (`int`, *optional*):
|
| 95 |
+
Maximum number of video frames to process.
|
| 96 |
+
ignore_index (`int`, *optional*, defaults to -100):
|
| 97 |
+
The index to ignore in loss computation.
|
| 98 |
+
proj_pos_emb (`bool`, *optional*, defaults to `True`):
|
| 99 |
+
Whether to use positional embeddings in the projector.
|
| 100 |
+
proj_prenorm (`bool`, *optional*, defaults to `False`):
|
| 101 |
+
Whether to apply pre-normalization in the projector.
|
| 102 |
+
use_1x1_grid (`bool`, *optional*, defaults to `False`):
|
| 103 |
+
Whether to use 1x1 grid for single-image processing.
|
| 104 |
+
possible_resolutions (`List[List[int]]`, *optional*):
|
| 105 |
+
List of possible resolutions `[height, width]` for any-resolution processing.
|
| 106 |
+
|
| 107 |
+
```python
|
| 108 |
+
>>> from configuration_hyperclovax_omni import HyperCLOVAXOmniConfig
|
| 109 |
+
|
| 110 |
+
>>> # Initializing a HyperCLOVAX-Omni configuration
|
| 111 |
+
>>> configuration = HyperCLOVAXOmniConfig()
|
| 112 |
+
```
|
| 113 |
+
"""
|
| 114 |
model_type = "hyperclovax_omni"
|
| 115 |
keys_to_ignore_at_inference = ["past_key_values"]
|
| 116 |
|
| 117 |
+
sub_configs = {
|
| 118 |
+
"text_config": AutoConfig,
|
| 119 |
+
"vision_config": AutoConfig,
|
| 120 |
+
"audio_config": AutoConfig,
|
| 121 |
+
"discrete_vision_config": AutoConfig,
|
| 122 |
+
"discrete_audio_config": AutoConfig,
|
| 123 |
+
"video_audio_compressor_config": AutoConfig,
|
| 124 |
+
}
|
| 125 |
|
| 126 |
@classmethod
|
| 127 |
+
def from_pretrained(cls, pretrained_model_name_or_path: str, **kwargs) -> "HyperCLOVAXOmniConfig":
|
| 128 |
config = super().from_pretrained(pretrained_model_name_or_path, **kwargs)
|
| 129 |
+
# Propagate _name_or_path to sub-configs so that AutoModel.from_config()
|
| 130 |
+
# can resolve dynamic module references (auto_map) from the checkpoint directory.
|
| 131 |
+
for attr in cls.sub_configs:
|
| 132 |
sub_config = getattr(config, attr, None)
|
| 133 |
if sub_config is not None and hasattr(sub_config, "_name_or_path"):
|
| 134 |
sub_config._name_or_path = config._name_or_path
|
|
|
|
| 136 |
|
| 137 |
def __init__(
|
| 138 |
self,
|
| 139 |
+
text_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 140 |
+
vision_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 141 |
+
discrete_vision_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 142 |
+
audio_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 143 |
+
discrete_audio_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 144 |
+
mm_projector_type: str = "mlp",
|
| 145 |
+
audio_projector_type: str = "mlp",
|
| 146 |
+
video_audio_compressor_type: Optional[str] = None,
|
| 147 |
+
video_audio_compressor_config: Optional[Union[Dict, PretrainedConfig]] = None,
|
| 148 |
+
vision_feature_layer: int = -2,
|
| 149 |
+
discrete_image_unit_0_id: int = 135166, # <|vision00000|>
|
| 150 |
+
discrete_audio_unit_0_id: int = 128604, # <|audio0000|>
|
| 151 |
+
anyres: bool = False,
|
| 152 |
+
unpad: bool = False,
|
| 153 |
+
max_num_grids: int = -1,
|
| 154 |
+
num_queries_vis_abstractor: int = -1,
|
| 155 |
+
video_num_queries_fast: Optional[int] = None,
|
| 156 |
+
video_num_queries_slow: Optional[int] = None,
|
| 157 |
+
video_first_last_frames_slows: Optional[int] = None,
|
| 158 |
+
video_max_num_frames: Optional[int] = None,
|
| 159 |
+
ignore_index: int = -100,
|
| 160 |
+
proj_pos_emb: bool = True,
|
| 161 |
+
proj_prenorm: bool = False,
|
| 162 |
+
use_1x1_grid: bool = False,
|
| 163 |
+
possible_resolutions: Optional[List[List[int]]] = None,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
**kwargs,
|
| 165 |
):
|
| 166 |
+
super().__init__(**kwargs)
|
| 167 |
# text_config
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 168 |
if isinstance(text_config, dict):
|
| 169 |
if text_config["model_type"] == "hyperclovax":
|
| 170 |
text_config = HyperCLOVAXConfig(**text_config)
|
|
|
|
| 172 |
text_config = LlamaConfig(**text_config)
|
| 173 |
else:
|
| 174 |
raise ValueError(f'Invalid text_config type: {text_config["model_type"]}')
|
| 175 |
+
if text_config is not None:
|
| 176 |
+
self.hidden_size = text_config.hidden_size
|
| 177 |
+
else:
|
| 178 |
+
self.hidden_size = kwargs.get("hidden_size", 4096)
|
| 179 |
self.text_config = text_config
|
| 180 |
+
|
| 181 |
# audio_config
|
|
|
|
|
|
|
| 182 |
if isinstance(audio_config, dict):
|
| 183 |
if audio_config["model_type"] == "qwen2_audio_encoder":
|
| 184 |
audio_config = Qwen2AudioEncoderConfig(**audio_config)
|
|
|
|
| 187 |
else:
|
| 188 |
raise ValueError(f'Invalid audio_config type: {audio_config["model_type"]}')
|
| 189 |
self.audio_config = audio_config
|
| 190 |
+
|
| 191 |
# discrete_audio_config
|
| 192 |
+
if isinstance(discrete_audio_config, dict):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 193 |
discrete_audio_config = CosyVoice2Config.from_dict(discrete_audio_config)
|
| 194 |
self.discrete_audio_config = discrete_audio_config
|
| 195 |
+
|
| 196 |
# vision_config
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
if isinstance(vision_config, dict):
|
| 198 |
if vision_config["model_type"] == "clip_vision_model":
|
| 199 |
vision_config = CLIPVisionConfig(**vision_config)
|
|
|
|
| 204 |
else:
|
| 205 |
raise ValueError(f'Invalid vision_config type: {vision_config["model_type"]}')
|
| 206 |
self.vision_config = vision_config
|
| 207 |
+
|
| 208 |
# discrete_vision_config
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 209 |
if isinstance(discrete_vision_config, dict):
|
| 210 |
discrete_vision_config = TATokConfig.from_dict(discrete_vision_config)
|
| 211 |
self.discrete_vision_config = discrete_vision_config
|
|
|
|
| 216 |
self.video_audio_compressor_config = video_audio_compressor_config
|
| 217 |
|
| 218 |
# add VLM configs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
self.mm_projector_type = mm_projector_type
|
| 220 |
self.audio_projector_type = audio_projector_type
|
| 221 |
self.video_audio_compressor_type = video_audio_compressor_type
|
| 222 |
+
self.vision_feature_layer = vision_feature_layer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 223 |
self.anyres = anyres
|
| 224 |
self.unpad = unpad
|
| 225 |
self.max_num_grids = max_num_grids
|
|
|
|
| 229 |
self.video_first_last_frames_slows = video_first_last_frames_slows
|
| 230 |
self.video_max_num_frames = video_max_num_frames
|
| 231 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
self.discrete_image_unit_0_id = discrete_image_unit_0_id
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 233 |
self.discrete_audio_unit_0_id = discrete_audio_unit_0_id
|
| 234 |
|
| 235 |
self.ignore_index = ignore_index
|
| 236 |
self.proj_pos_emb = proj_pos_emb
|
| 237 |
self.proj_prenorm = proj_prenorm
|
| 238 |
self.use_1x1_grid = use_1x1_grid
|
| 239 |
+
self.possible_resolutions = possible_resolutions if possible_resolutions is not None else []
|
| 240 |
+
|
|
|
|
|
|
|
| 241 |
# needed for HCXVisionForSequenceClassification
|
| 242 |
+
if self.text_config is not None:
|
| 243 |
self.pad_token_id = self.text_config.pad_token_id
|
|
|
|
|
|
|
| 244 |
|
| 245 |
|
| 246 |
+
AutoConfig.register("hyperclovax_omni", HyperCLOVAXOmniConfig)
|
| 247 |
+
|
| 248 |
+
__all__ = ["HyperCLOVAXOmniConfig"]
|
configuration_mambamia.py
CHANGED
|
@@ -1,19 +1,41 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from transformers.configuration_utils import PretrainedConfig
|
| 4 |
|
| 5 |
|
| 6 |
-
# MambaMia VideoAudio Compressor Config
|
| 7 |
class MambaMiaVideoAudioCompressorConfig(PretrainedConfig):
|
| 8 |
-
"""
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
Args:
|
| 12 |
-
input_size
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
"""
|
| 18 |
|
| 19 |
model_type = "mambamia_videoaudio_compressor"
|
|
@@ -33,6 +55,8 @@ class MambaMiaVideoAudioCompressorConfig(PretrainedConfig):
|
|
| 33 |
self.chunk_size = chunk_size
|
| 34 |
self.num_hidden_layers = num_hidden_layers
|
| 35 |
self.hidden_size = hidden_size
|
| 36 |
-
|
| 37 |
-
|
|
|
|
|
|
|
| 38 |
__all__ = ["MambaMiaVideoAudioCompressorConfig"]
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 NAVER Cloud Corp. and the HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""MambaMia video-audio compressor configuration"""
|
| 16 |
+
|
| 17 |
+
from transformers import AutoConfig
|
| 18 |
from transformers.configuration_utils import PretrainedConfig
|
| 19 |
|
| 20 |
|
|
|
|
| 21 |
class MambaMiaVideoAudioCompressorConfig(PretrainedConfig):
|
| 22 |
+
r"""
|
| 23 |
+
This is the configuration class to store the configuration of a MambaMia video-audio compressor.
|
| 24 |
+
|
| 25 |
+
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 26 |
+
documentation from [`PretrainedConfig`] for more information.
|
| 27 |
|
| 28 |
Args:
|
| 29 |
+
input_size (`int`, *optional*, defaults to 1280):
|
| 30 |
+
Input embedding dimension (e.g., 1280 for Whisper encoder output).
|
| 31 |
+
output_size (`int`, *optional*, defaults to 2048):
|
| 32 |
+
Output embedding dimension (e.g., 2048 for LLM hidden size).
|
| 33 |
+
chunk_size (`int`, *optional*, defaults to 25):
|
| 34 |
+
Number of tokens per chunk (i.e., 1 second at 25Hz).
|
| 35 |
+
num_hidden_layers (`int`, *optional*, defaults to 1):
|
| 36 |
+
Number of MambaMia2 layers.
|
| 37 |
+
hidden_size (`int`, *optional*, defaults to 3072):
|
| 38 |
+
Internal hidden size. Must be divisible by 24.
|
| 39 |
"""
|
| 40 |
|
| 41 |
model_type = "mambamia_videoaudio_compressor"
|
|
|
|
| 55 |
self.chunk_size = chunk_size
|
| 56 |
self.num_hidden_layers = num_hidden_layers
|
| 57 |
self.hidden_size = hidden_size
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
AutoConfig.register("mambamia_videoaudio_compressor", MambaMiaVideoAudioCompressorConfig)
|
| 61 |
+
|
| 62 |
__all__ = ["MambaMiaVideoAudioCompressorConfig"]
|
configuration_tatok.py
CHANGED
|
@@ -1,13 +1,57 @@
|
|
| 1 |
-
|
| 2 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from transformers.configuration_utils import PretrainedConfig
|
| 4 |
|
| 5 |
|
| 6 |
-
# TATok (TextAlignedTokenizer) Config
|
| 7 |
class TATokConfig(PretrainedConfig):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
model_type = "tatok"
|
| 9 |
|
| 10 |
-
|
| 11 |
"name": "bottleneck",
|
| 12 |
"args": {
|
| 13 |
"bottleneck_dim": 1536,
|
|
@@ -33,125 +77,29 @@ class TATokConfig(PretrainedConfig):
|
|
| 33 |
|
| 34 |
def __init__(
|
| 35 |
self,
|
| 36 |
-
bottleneck=None,
|
| 37 |
-
bottleneck_token_num=729,
|
| 38 |
-
input_size=384,
|
| 39 |
-
teacher="google/siglip2-so400m-patch14-384",
|
| 40 |
-
input_type="indices",
|
| 41 |
-
pool_scale=1,
|
| 42 |
-
decoder_depth=3,
|
| 43 |
-
select_layer_id=-2,
|
| 44 |
-
|
| 45 |
**kwargs,
|
| 46 |
):
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
kwargs_select_layer_id = kwargs.pop("select_layer_id", -2)
|
| 58 |
-
kwargs_model_name_or_path = kwargs.pop("model_name_or_path", None)
|
| 59 |
-
|
| 60 |
-
# Also handle ckpt_path which might be in kwargs from config.json
|
| 61 |
-
ckpt_path = kwargs.pop("ckpt_path", None)
|
| 62 |
-
if ckpt_path is not None:
|
| 63 |
-
kwargs_teacher = ckpt_path
|
| 64 |
-
# Store ckpt_path to include in merged_kwargs later
|
| 65 |
-
stored_ckpt_path = ckpt_path
|
| 66 |
-
else:
|
| 67 |
-
stored_ckpt_path = None
|
| 68 |
-
|
| 69 |
-
# Use explicit arguments if they differ from defaults, otherwise use kwargs values.
|
| 70 |
-
# For bottleneck, if everything is None, fall back to the full default hierarchical config.
|
| 71 |
-
if bottleneck is not None:
|
| 72 |
-
self.bottleneck = bottleneck
|
| 73 |
-
elif kwargs_bottleneck is not None:
|
| 74 |
-
self.bottleneck = kwargs_bottleneck
|
| 75 |
-
else:
|
| 76 |
-
self.bottleneck = self.default_tatok_bottleneck
|
| 77 |
-
|
| 78 |
-
self.bottleneck_token_num = bottleneck_token_num if bottleneck_token_num != 729 else kwargs_bottleneck_token_num
|
| 79 |
-
self.input_size = input_size if input_size != 384 else kwargs_input_size
|
| 80 |
-
self.teacher = teacher if teacher != "google/siglip2-so400m-patch14-384" else kwargs_teacher
|
| 81 |
-
self.input_type = input_type if input_type != "indices" else kwargs_input_type
|
| 82 |
-
self.pool_scale = pool_scale if pool_scale != 1 else kwargs_pool_scale
|
| 83 |
-
self.decoder_depth = decoder_depth if decoder_depth != 3 else kwargs_decoder_depth
|
| 84 |
-
self.select_layer_id = select_layer_id if select_layer_id != -2 else kwargs_select_layer_id
|
| 85 |
-
self.model_name_or_path = model_name_or_path if model_name_or_path is not None else kwargs_model_name_or_path
|
| 86 |
-
|
| 87 |
-
# Set default values for standard transformers config attributes
|
| 88 |
-
# These will be merged with kwargs so they appear even when not in config.json
|
| 89 |
-
default_transformers_config = {
|
| 90 |
-
"_name_or_path": None,
|
| 91 |
-
"add_cross_attention": False,
|
| 92 |
-
"architectures": ["TextAlignedTokenizer"],
|
| 93 |
-
"bad_words_ids": None,
|
| 94 |
-
"begin_suppress_tokens": None,
|
| 95 |
-
"bos_token_id": None,
|
| 96 |
-
"chunk_size_feed_forward": 0,
|
| 97 |
-
"cross_attention_hidden_size": None,
|
| 98 |
-
"decoder_start_token_id": None,
|
| 99 |
-
"diversity_penalty": 0.0,
|
| 100 |
-
"do_sample": False,
|
| 101 |
-
"early_stopping": False,
|
| 102 |
-
"encoder_no_repeat_ngram_size": 0,
|
| 103 |
-
"eos_token_id": None,
|
| 104 |
-
"exponential_decay_length_penalty": None,
|
| 105 |
-
"finetuning_task": None,
|
| 106 |
-
"forced_bos_token_id": None,
|
| 107 |
-
"forced_eos_token_id": None,
|
| 108 |
-
"id2label": {"0": "LABEL_0", "1": "LABEL_1"},
|
| 109 |
-
"is_decoder": False,
|
| 110 |
-
"is_encoder_decoder": False,
|
| 111 |
-
"label2id": {"LABEL_0": 0, "LABEL_1": 1},
|
| 112 |
-
"length_penalty": 1.0,
|
| 113 |
-
"max_length": 20,
|
| 114 |
-
"min_length": 0,
|
| 115 |
-
"no_repeat_ngram_size": 0,
|
| 116 |
-
"num_beam_groups": 1,
|
| 117 |
-
"num_beams": 1,
|
| 118 |
-
"num_return_sequences": 1,
|
| 119 |
-
"output_attentions": False,
|
| 120 |
-
"output_hidden_states": False,
|
| 121 |
-
"output_scores": False,
|
| 122 |
-
"pad_token_id": None,
|
| 123 |
-
"prefix": None,
|
| 124 |
-
"problem_type": None,
|
| 125 |
-
"pruned_heads": {},
|
| 126 |
-
"rand_scale": True,
|
| 127 |
-
"remove_invalid_values": False,
|
| 128 |
-
"repetition_penalty": 1.0,
|
| 129 |
-
"return_dict": True,
|
| 130 |
-
"return_dict_in_generate": False,
|
| 131 |
-
"sep_token_id": None,
|
| 132 |
-
"suppress_tokens": None,
|
| 133 |
-
"task_specific_params": None,
|
| 134 |
-
"temperature": 1.0,
|
| 135 |
-
"tf_legacy_loss": False,
|
| 136 |
-
"tie_encoder_decoder": False,
|
| 137 |
-
"tie_word_embeddings": True,
|
| 138 |
-
"tokenizer_class": None,
|
| 139 |
-
"top_k": 50,
|
| 140 |
-
"top_p": 1.0,
|
| 141 |
-
"torch_dtype": "float32",
|
| 142 |
-
"torchscript": False,
|
| 143 |
-
"typical_p": 1.0,
|
| 144 |
-
"use_bfloat16": False,
|
| 145 |
-
}
|
| 146 |
|
| 147 |
-
# Merge defaults with kwargs (kwargs values take precedence)
|
| 148 |
-
merged_kwargs = {**default_transformers_config, **kwargs}
|
| 149 |
|
| 150 |
-
|
| 151 |
-
if stored_ckpt_path is not None:
|
| 152 |
-
merged_kwargs["ckpt_path"] = stored_ckpt_path
|
| 153 |
|
| 154 |
-
# Pass merged kwargs to parent (these are standard transformers config attributes)
|
| 155 |
-
super().__init__(**merged_kwargs)
|
| 156 |
-
|
| 157 |
__all__ = ["TATokConfig"]
|
|
|
|
| 1 |
+
# coding=utf-8
|
| 2 |
+
# Copyright 2024 NAVER Cloud Corp. and the HuggingFace Inc. team. All rights reserved.
|
| 3 |
+
#
|
| 4 |
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 |
+
# you may not use this file except in compliance with the License.
|
| 6 |
+
# You may obtain a copy of the License at
|
| 7 |
+
#
|
| 8 |
+
# http://www.apache.org/licenses/LICENSE-2.0
|
| 9 |
+
#
|
| 10 |
+
# Unless required by applicable law or agreed to in writing, software
|
| 11 |
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 |
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 |
+
# See the License for the specific language governing permissions and
|
| 14 |
+
# limitations under the License.
|
| 15 |
+
"""TATok (Text-Aligned Tokenizer) configuration"""
|
| 16 |
+
|
| 17 |
+
import copy
|
| 18 |
+
from typing import Optional
|
| 19 |
+
|
| 20 |
+
from transformers import AutoConfig
|
| 21 |
from transformers.configuration_utils import PretrainedConfig
|
| 22 |
|
| 23 |
|
|
|
|
| 24 |
class TATokConfig(PretrainedConfig):
|
| 25 |
+
r"""
|
| 26 |
+
This is the configuration class to store the configuration of a TATok (Text-Aligned Tokenizer) model.
|
| 27 |
+
|
| 28 |
+
Configuration objects inherit from [`PretrainedConfig`] and can be used to control the model outputs. Read the
|
| 29 |
+
documentation from [`PretrainedConfig`] for more information.
|
| 30 |
+
|
| 31 |
+
Args:
|
| 32 |
+
bottleneck (`dict`, *optional*):
|
| 33 |
+
Configuration dict for the bottleneck layer. If not provided, uses `TATokConfig._default_bottleneck`.
|
| 34 |
+
bottleneck_token_num (`int`, *optional*, defaults to 729):
|
| 35 |
+
Number of bottleneck tokens.
|
| 36 |
+
input_size (`int`, *optional*, defaults to 384):
|
| 37 |
+
Input image size.
|
| 38 |
+
teacher (`str`, *optional*, defaults to `"google/siglip2-so400m-patch14-384"`):
|
| 39 |
+
Name or path of the teacher model.
|
| 40 |
+
input_type (`str`, *optional*, defaults to `"indices"`):
|
| 41 |
+
Type of input representation.
|
| 42 |
+
pool_scale (`int`, *optional*, defaults to 1):
|
| 43 |
+
Pooling scale factor.
|
| 44 |
+
decoder_depth (`int`, *optional*, defaults to 3):
|
| 45 |
+
Number of decoder layers.
|
| 46 |
+
select_layer_id (`int`, *optional*, defaults to -2):
|
| 47 |
+
Index of the teacher layer to select features from.
|
| 48 |
+
rand_scale (`bool`, *optional*, defaults to `True`):
|
| 49 |
+
Whether to use random scaling during training.
|
| 50 |
+
"""
|
| 51 |
+
|
| 52 |
model_type = "tatok"
|
| 53 |
|
| 54 |
+
_default_bottleneck = {
|
| 55 |
"name": "bottleneck",
|
| 56 |
"args": {
|
| 57 |
"bottleneck_dim": 1536,
|
|
|
|
| 77 |
|
| 78 |
def __init__(
|
| 79 |
self,
|
| 80 |
+
bottleneck: Optional[dict] = None,
|
| 81 |
+
bottleneck_token_num: int = 729,
|
| 82 |
+
input_size: int = 384,
|
| 83 |
+
teacher: str = "google/siglip2-so400m-patch14-384",
|
| 84 |
+
input_type: str = "indices",
|
| 85 |
+
pool_scale: int = 1,
|
| 86 |
+
decoder_depth: int = 3,
|
| 87 |
+
select_layer_id: int = -2,
|
| 88 |
+
rand_scale: bool = True,
|
| 89 |
**kwargs,
|
| 90 |
):
|
| 91 |
+
super().__init__(**kwargs)
|
| 92 |
+
self.bottleneck = bottleneck if bottleneck is not None else copy.deepcopy(self._default_bottleneck)
|
| 93 |
+
self.bottleneck_token_num = bottleneck_token_num
|
| 94 |
+
self.input_size = input_size
|
| 95 |
+
self.teacher = teacher
|
| 96 |
+
self.input_type = input_type
|
| 97 |
+
self.pool_scale = pool_scale
|
| 98 |
+
self.decoder_depth = decoder_depth
|
| 99 |
+
self.select_layer_id = select_layer_id
|
| 100 |
+
self.rand_scale = rand_scale
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
|
|
|
|
|
|
| 102 |
|
| 103 |
+
AutoConfig.register("tatok", TATokConfig)
|
|
|
|
|
|
|
| 104 |
|
|
|
|
|
|
|
|
|
|
| 105 |
__all__ = ["TATokConfig"]
|
image_processing_hyperclovax_omni.py
CHANGED
|
@@ -1,19 +1,19 @@
|
|
| 1 |
"""
|
| 2 |
-
|
| 3 |
|
| 4 |
-
|
| 5 |
-
- Smart resize:
|
| 6 |
-
- Vision token calculation:
|
| 7 |
-
- Discrete image processing:
|
| 8 |
|
| 9 |
-
BaseImageProcessorFast
|
| 10 |
-
Track A (Qwen2VLImageProcessorFast)와 bit-perfect 일치를 달성합니다.
|
| 11 |
"""
|
| 12 |
|
| 13 |
-
import os
|
| 14 |
import math
|
|
|
|
|
|
|
|
|
|
| 15 |
import torch
|
| 16 |
-
from typing import Dict, List, Optional, Union, Tuple
|
| 17 |
from torchvision.transforms.v2 import functional as F
|
| 18 |
from transformers.image_processing_utils import BatchFeature
|
| 19 |
from transformers.image_processing_utils_fast import (
|
|
@@ -32,29 +32,31 @@ from transformers.image_utils import (
|
|
| 32 |
from transformers.processing_utils import ImagesKwargs, Unpack
|
| 33 |
from transformers.utils import TensorType, logging
|
| 34 |
|
| 35 |
-
|
| 36 |
logger = logging.get_logger(__name__)
|
| 37 |
|
| 38 |
|
| 39 |
def smart_resize(
|
| 40 |
-
height: int,
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
Args:
|
| 50 |
-
height:
|
| 51 |
-
width:
|
| 52 |
-
factor:
|
| 53 |
-
min_pixels:
|
| 54 |
-
max_pixels:
|
| 55 |
|
| 56 |
Returns:
|
| 57 |
-
(new_height, new_width)
|
| 58 |
"""
|
| 59 |
if max(height, width) / min(height, width) > 200:
|
| 60 |
raise ValueError(
|
|
@@ -73,18 +75,22 @@ def smart_resize(
|
|
| 73 |
return h_bar, w_bar
|
| 74 |
|
| 75 |
|
| 76 |
-
def
|
| 77 |
-
|
| 78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
| 80 |
Args:
|
| 81 |
-
height: Image height (should be divisible by patch_size * merge_size)
|
| 82 |
-
width: Image width (should be divisible by patch_size * merge_size)
|
| 83 |
-
patch_size: ViT patch size (default: 14)
|
| 84 |
-
merge_size: Merge size for token reduction (default: 2)
|
| 85 |
|
| 86 |
Returns:
|
| 87 |
-
Number of vision tokens
|
| 88 |
"""
|
| 89 |
grid_h = height // patch_size
|
| 90 |
grid_w = width // patch_size
|
|
@@ -98,14 +104,6 @@ class HyperCLOVAXOmniFastImageProcessorKwargs(DefaultFastImageProcessorKwargs, t
|
|
| 98 |
patch_size: Optional[int]
|
| 99 |
temporal_patch_size: Optional[int]
|
| 100 |
merge_size: Optional[int]
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
class HyperCLOVAXOmniImagesKwargs(ImagesKwargs, total=False):
|
| 104 |
-
min_pixels: Optional[int]
|
| 105 |
-
max_pixels: Optional[int]
|
| 106 |
-
patch_size: Optional[int]
|
| 107 |
-
temporal_patch_size: Optional[int]
|
| 108 |
-
merge_size: Optional[int]
|
| 109 |
# Token parameters
|
| 110 |
image_token: Optional[str]
|
| 111 |
image_start_token: Optional[str]
|
|
@@ -123,19 +121,15 @@ class HyperCLOVAXOmniImagesKwargs(ImagesKwargs, total=False):
|
|
| 123 |
|
| 124 |
|
| 125 |
class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
| 126 |
-
"""
|
| 127 |
-
Fast image processor for HyperCLOVAXOmni that follows Qwen VL's image processing logic.
|
| 128 |
|
| 129 |
-
Uses torchvision-based resize
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
|
| 133 |
-
1. Smart resize: adjusts image size to be within min_pixels and max_pixels
|
| 134 |
-
2. Vision token calculation: uses merge_size for token reduction
|
| 135 |
-
3. Discrete image processing: separate processing for discrete vision tokens
|
| 136 |
"""
|
| 137 |
|
| 138 |
-
# Class-level defaults
|
| 139 |
resample = PILImageResampling.BICUBIC
|
| 140 |
image_mean = OPENAI_CLIP_MEAN
|
| 141 |
image_std = OPENAI_CLIP_STD
|
|
@@ -154,7 +148,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 154 |
valid_kwargs = HyperCLOVAXOmniFastImageProcessorKwargs
|
| 155 |
|
| 156 |
def __init__(self, **kwargs):
|
| 157 |
-
# Handle size
|
| 158 |
size = kwargs.pop("size", None)
|
| 159 |
min_pixels = kwargs.pop("min_pixels", None)
|
| 160 |
max_pixels = kwargs.pop("max_pixels", None)
|
|
@@ -192,7 +186,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 192 |
if self.max_pixels is None:
|
| 193 |
self.max_pixels = self.size["longest_edge"]
|
| 194 |
|
| 195 |
-
# Build ratio
|
| 196 |
ratios = self.discrete_image_ratios if self.discrete_image_ratios is not None else []
|
| 197 |
self.discrete_image_ratio_tokens = {
|
| 198 |
f"{r[0]}:{r[1]}": f"<|vision_ratio_{r[0]}:{r[1]}|>"
|
|
@@ -206,7 +200,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 206 |
max_pixels: Optional[int] = None,
|
| 207 |
**kwargs,
|
| 208 |
) -> dict:
|
| 209 |
-
"""size
|
| 210 |
if min_pixels is not None and max_pixels is not None:
|
| 211 |
size = {"shortest_edge": min_pixels, "longest_edge": max_pixels}
|
| 212 |
elif size is not None:
|
|
@@ -219,12 +213,41 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 219 |
|
| 220 |
return super()._further_process_kwargs(size=size, min_pixels=min_pixels, max_pixels=max_pixels, **kwargs)
|
| 221 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 222 |
def _preprocess_continuous_image(
|
| 223 |
self,
|
| 224 |
images: list,
|
| 225 |
do_resize: bool,
|
| 226 |
size: SizeDict,
|
| 227 |
-
interpolation: Optional[
|
| 228 |
do_rescale: bool,
|
| 229 |
rescale_factor: float,
|
| 230 |
do_normalize: bool,
|
|
@@ -235,29 +258,30 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 235 |
merge_size: int,
|
| 236 |
disable_grouping: Optional[bool],
|
| 237 |
) -> dict:
|
| 238 |
-
"""
|
| 239 |
|
| 240 |
-
|
| 241 |
|
| 242 |
Args:
|
| 243 |
-
images:
|
| 244 |
-
do_resize:
|
| 245 |
-
size: min_pixels/max_pixels
|
| 246 |
-
interpolation:
|
| 247 |
-
do_rescale:
|
| 248 |
-
rescale_factor:
|
| 249 |
-
do_normalize:
|
| 250 |
-
image_mean:
|
| 251 |
-
image_std:
|
| 252 |
-
patch_size: ViT
|
| 253 |
-
temporal_patch_size:
|
| 254 |
-
merge_size:
|
| 255 |
-
disable_grouping:
|
| 256 |
|
| 257 |
Returns:
|
| 258 |
-
|
| 259 |
-
- "pixel_values": (N, num_patches, patch_dim)
|
| 260 |
-
- "image_grid_thw": (N, 3)
|
|
|
|
| 261 |
"""
|
| 262 |
# 1. Group & smart resize
|
| 263 |
grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
|
|
@@ -279,7 +303,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 279 |
resized_images_grouped[shape] = stacked_images
|
| 280 |
resized_images = reorder_images(resized_images_grouped, grouped_images_index)
|
| 281 |
|
| 282 |
-
# 2. Group again
|
| 283 |
grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
|
| 284 |
processed_images_grouped = {}
|
| 285 |
processed_grids = {}
|
|
@@ -303,7 +327,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 303 |
grid_t = grid_t // temporal_patch_size
|
| 304 |
grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
|
| 305 |
|
| 306 |
-
# Patchify: reshape
|
| 307 |
patches = patches.view(
|
| 308 |
batch_size,
|
| 309 |
grid_t, temporal_patch_size,
|
|
@@ -338,22 +362,23 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 338 |
self,
|
| 339 |
images: list,
|
| 340 |
original_sizes: List[Tuple[int, int]],
|
| 341 |
-
interpolation: Optional[
|
| 342 |
) -> dict:
|
| 343 |
-
"""
|
| 344 |
|
| 345 |
-
|
| 346 |
-
|
| 347 |
|
| 348 |
Args:
|
| 349 |
-
images:
|
| 350 |
-
original_sizes:
|
| 351 |
-
interpolation:
|
| 352 |
|
| 353 |
Returns:
|
| 354 |
-
|
| 355 |
-
- "discrete_pixel_values": (N, C, discrete_image_size, discrete_image_size)
|
| 356 |
-
- "discrete_image_ratios": (N, 2)
|
|
|
|
| 357 |
"""
|
| 358 |
discrete_pixel_values_list = []
|
| 359 |
discrete_image_ratios_list = []
|
|
@@ -393,7 +418,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 393 |
images: list,
|
| 394 |
do_resize: bool,
|
| 395 |
size: SizeDict,
|
| 396 |
-
interpolation: Optional[
|
| 397 |
do_rescale: bool,
|
| 398 |
rescale_factor: float,
|
| 399 |
do_normalize: bool,
|
|
@@ -405,12 +430,36 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 405 |
disable_grouping: Optional[bool],
|
| 406 |
return_tensors: Optional[Union[str, TensorType]],
|
| 407 |
**kwargs,
|
| 408 |
-
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 409 |
# Record original sizes for discrete processing before any transforms
|
| 410 |
if self.use_discrete_image_token:
|
| 411 |
original_sizes = [(img.shape[-2], img.shape[-1]) for img in images]
|
| 412 |
|
| 413 |
-
#
|
| 414 |
continuous_result = self._preprocess_continuous_image(
|
| 415 |
images,
|
| 416 |
do_resize=do_resize,
|
|
@@ -428,7 +477,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 428 |
)
|
| 429 |
data = continuous_result
|
| 430 |
|
| 431 |
-
#
|
| 432 |
if self.use_discrete_image_token:
|
| 433 |
discrete_result = self._preprocess_discrete_image(
|
| 434 |
images,
|
|
@@ -439,39 +488,35 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 439 |
|
| 440 |
return BatchFeature(data=data, tensor_type=return_tensors)
|
| 441 |
|
| 442 |
-
def _find_best_ratio_token(
|
| 443 |
-
self,
|
| 444 |
-
original_size: List[int],
|
| 445 |
-
discrete_image_ratios: Optional[List[List[int]]] = None,
|
| 446 |
-
):
|
| 447 |
-
"""Find the best ratio token based on original_size"""
|
| 448 |
-
discrete_image_ratios = discrete_image_ratios if discrete_image_ratios is not None else self.discrete_image_ratios
|
| 449 |
-
|
| 450 |
-
if not discrete_image_ratios:
|
| 451 |
-
return (1, 1)
|
| 452 |
-
|
| 453 |
-
h, w = original_size
|
| 454 |
-
if h == 0 or w == 0:
|
| 455 |
-
return (1, 1)
|
| 456 |
-
|
| 457 |
-
ratios = [i / j for i, j in discrete_image_ratios]
|
| 458 |
-
diffs = [abs(w / h - r) for r in ratios]
|
| 459 |
-
best_size_idx = diffs.index(min(diffs))
|
| 460 |
-
|
| 461 |
-
return discrete_image_ratios[best_size_idx]
|
| 462 |
-
|
| 463 |
def get_num_image_tokens(
|
| 464 |
self,
|
| 465 |
image_width: Optional[int] = None,
|
| 466 |
image_height: Optional[int] = None,
|
| 467 |
-
pixel_values: Optional[
|
| 468 |
include_boundary_tokens: bool = False,
|
| 469 |
min_pixels: Optional[int] = None,
|
| 470 |
max_pixels: Optional[int] = None,
|
| 471 |
patch_size: Optional[int] = None,
|
| 472 |
merge_size: Optional[int] = None,
|
|
|
|
| 473 |
) -> int:
|
| 474 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
patch_size = patch_size if patch_size is not None else self.patch_size
|
| 476 |
merge_size = merge_size if merge_size is not None else self.merge_size
|
| 477 |
min_pixels = min_pixels if min_pixels is not None else self.min_pixels
|
|
@@ -483,7 +528,7 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 483 |
resized_height, resized_width = smart_resize(
|
| 484 |
image_height, image_width, factor=factor, min_pixels=min_pixels, max_pixels=max_pixels
|
| 485 |
)
|
| 486 |
-
num_patches =
|
| 487 |
num_continuous_tokens = num_patches // (merge_size ** 2)
|
| 488 |
elif len(pixel_values.shape) == 2:
|
| 489 |
num_continuous_tokens = pixel_values.shape[0] // (merge_size ** 2)
|
|
@@ -492,23 +537,31 @@ class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
|
| 492 |
pv.shape[0] // (merge_size ** 2) for pv in pixel_values
|
| 493 |
)
|
| 494 |
if include_boundary_tokens:
|
| 495 |
-
num_continuous_tokens += 2
|
| 496 |
|
| 497 |
if self.use_discrete_image_token:
|
| 498 |
discrete_token_size = self.discrete_token_size
|
| 499 |
-
num_discrete_tokens = discrete_token_size ** 2
|
| 500 |
-
# num_discrete_tokens += discrete_token_size # vision_eol
|
| 501 |
-
# num_discrete_tokens += 1 # vision_eof
|
| 502 |
if include_boundary_tokens:
|
| 503 |
-
num_discrete_tokens += 2
|
| 504 |
|
| 505 |
-
|
|
|
|
|
|
|
|
|
|
| 506 |
|
| 507 |
def save_pretrained(
|
| 508 |
self,
|
| 509 |
save_directory: Union[str, os.PathLike],
|
| 510 |
*args,
|
| 511 |
**kwargs,
|
| 512 |
-
):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 513 |
self.register_for_auto_class()
|
| 514 |
super().save_pretrained(save_directory, *args, **kwargs)
|
|
|
|
| 1 |
"""
|
| 2 |
+
HyperCLOVAX Omni Image Processor (Fast)
|
| 3 |
|
| 4 |
+
Implements dynamic resolution image processing:
|
| 5 |
+
- Smart resize: adjusts image to fit within min_pixels and max_pixels
|
| 6 |
+
- Vision token calculation: token reduction using merge_size
|
| 7 |
+
- Discrete image processing: separate processing for discrete vision tokens
|
| 8 |
|
| 9 |
+
Based on BaseImageProcessorFast with torchvision resize.
|
|
|
|
| 10 |
"""
|
| 11 |
|
|
|
|
| 12 |
import math
|
| 13 |
+
import os
|
| 14 |
+
from typing import List, Optional, Tuple, Union
|
| 15 |
+
|
| 16 |
import torch
|
|
|
|
| 17 |
from torchvision.transforms.v2 import functional as F
|
| 18 |
from transformers.image_processing_utils import BatchFeature
|
| 19 |
from transformers.image_processing_utils_fast import (
|
|
|
|
| 32 |
from transformers.processing_utils import ImagesKwargs, Unpack
|
| 33 |
from transformers.utils import TensorType, logging
|
| 34 |
|
|
|
|
| 35 |
logger = logging.get_logger(__name__)
|
| 36 |
|
| 37 |
|
| 38 |
def smart_resize(
|
| 39 |
+
height: int,
|
| 40 |
+
width: int,
|
| 41 |
+
factor: int = 28,
|
| 42 |
+
min_pixels: int = 56 * 56,
|
| 43 |
+
max_pixels: int = 14 * 14 * 4 * 1280,
|
| 44 |
+
) -> Tuple[int, int]:
|
| 45 |
+
"""Smart resize for dynamic resolution.
|
| 46 |
+
|
| 47 |
+
Adjusts image dimensions to satisfy:
|
| 48 |
+
1. Both dimensions are divisible by factor.
|
| 49 |
+
2. Total pixel count is between min_pixels and max_pixels.
|
| 50 |
|
| 51 |
Args:
|
| 52 |
+
height: Original image height.
|
| 53 |
+
width: Original image width.
|
| 54 |
+
factor: Rounding unit (default: 28 = patch_size * merge_size).
|
| 55 |
+
min_pixels: Minimum pixel count (default: 3136).
|
| 56 |
+
max_pixels: Maximum pixel count (default: 1003520).
|
| 57 |
|
| 58 |
Returns:
|
| 59 |
+
Tuple of (new_height, new_width).
|
| 60 |
"""
|
| 61 |
if max(height, width) / min(height, width) > 200:
|
| 62 |
raise ValueError(
|
|
|
|
| 75 |
return h_bar, w_bar
|
| 76 |
|
| 77 |
|
| 78 |
+
def calculate_num_patches(
|
| 79 |
+
height: int,
|
| 80 |
+
width: int,
|
| 81 |
+
patch_size: int = 14,
|
| 82 |
+
merge_size: int = 2,
|
| 83 |
+
) -> int:
|
| 84 |
+
"""Calculate the number of vision tokens.
|
| 85 |
|
| 86 |
Args:
|
| 87 |
+
height: Image height (should be divisible by patch_size * merge_size).
|
| 88 |
+
width: Image width (should be divisible by patch_size * merge_size).
|
| 89 |
+
patch_size: ViT patch size (default: 14).
|
| 90 |
+
merge_size: Merge size for token reduction (default: 2).
|
| 91 |
|
| 92 |
Returns:
|
| 93 |
+
Number of vision tokens.
|
| 94 |
"""
|
| 95 |
grid_h = height // patch_size
|
| 96 |
grid_w = width // patch_size
|
|
|
|
| 104 |
patch_size: Optional[int]
|
| 105 |
temporal_patch_size: Optional[int]
|
| 106 |
merge_size: Optional[int]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
# Token parameters
|
| 108 |
image_token: Optional[str]
|
| 109 |
image_start_token: Optional[str]
|
|
|
|
| 121 |
|
| 122 |
|
| 123 |
class HyperCLOVAXOmniImageProcessor(BaseImageProcessorFast):
|
| 124 |
+
"""Fast image processor for HyperCLOVAX Omni.
|
|
|
|
| 125 |
|
| 126 |
+
Uses torchvision-based resize for dynamic resolution processing:
|
| 127 |
+
1. Smart resize: adjusts image size to be within min_pixels and max_pixels.
|
| 128 |
+
2. Vision token calculation: uses merge_size for token reduction.
|
| 129 |
+
3. Discrete image processing: separate processing for discrete vision tokens.
|
|
|
|
|
|
|
|
|
|
| 130 |
"""
|
| 131 |
|
| 132 |
+
# Class-level defaults
|
| 133 |
resample = PILImageResampling.BICUBIC
|
| 134 |
image_mean = OPENAI_CLIP_MEAN
|
| 135 |
image_std = OPENAI_CLIP_STD
|
|
|
|
| 148 |
valid_kwargs = HyperCLOVAXOmniFastImageProcessorKwargs
|
| 149 |
|
| 150 |
def __init__(self, **kwargs):
|
| 151 |
+
# Handle size <-> min_pixels/max_pixels
|
| 152 |
size = kwargs.pop("size", None)
|
| 153 |
min_pixels = kwargs.pop("min_pixels", None)
|
| 154 |
max_pixels = kwargs.pop("max_pixels", None)
|
|
|
|
| 186 |
if self.max_pixels is None:
|
| 187 |
self.max_pixels = self.size["longest_edge"]
|
| 188 |
|
| 189 |
+
# Build ratio -> token mapping from discrete_image_ratios
|
| 190 |
ratios = self.discrete_image_ratios if self.discrete_image_ratios is not None else []
|
| 191 |
self.discrete_image_ratio_tokens = {
|
| 192 |
f"{r[0]}:{r[1]}": f"<|vision_ratio_{r[0]}:{r[1]}|>"
|
|
|
|
| 200 |
max_pixels: Optional[int] = None,
|
| 201 |
**kwargs,
|
| 202 |
) -> dict:
|
| 203 |
+
"""Synchronize size <-> min_pixels/max_pixels."""
|
| 204 |
if min_pixels is not None and max_pixels is not None:
|
| 205 |
size = {"shortest_edge": min_pixels, "longest_edge": max_pixels}
|
| 206 |
elif size is not None:
|
|
|
|
| 213 |
|
| 214 |
return super()._further_process_kwargs(size=size, min_pixels=min_pixels, max_pixels=max_pixels, **kwargs)
|
| 215 |
|
| 216 |
+
def _find_best_ratio_token(
|
| 217 |
+
self,
|
| 218 |
+
original_size: List[int],
|
| 219 |
+
discrete_image_ratios: Optional[List[List[int]]] = None,
|
| 220 |
+
) -> Tuple[int, int]:
|
| 221 |
+
"""Find the best ratio token based on the original image aspect ratio.
|
| 222 |
+
|
| 223 |
+
Args:
|
| 224 |
+
original_size: Original [height, width] of the image.
|
| 225 |
+
discrete_image_ratios: List of [h, w] ratio pairs. Defaults to self.discrete_image_ratios.
|
| 226 |
+
|
| 227 |
+
Returns:
|
| 228 |
+
Best matching (h_ratio, w_ratio) tuple.
|
| 229 |
+
"""
|
| 230 |
+
discrete_image_ratios = discrete_image_ratios if discrete_image_ratios is not None else self.discrete_image_ratios
|
| 231 |
+
|
| 232 |
+
if not discrete_image_ratios:
|
| 233 |
+
return (1, 1)
|
| 234 |
+
|
| 235 |
+
h, w = original_size
|
| 236 |
+
if h == 0 or w == 0:
|
| 237 |
+
return (1, 1)
|
| 238 |
+
|
| 239 |
+
ratios = [i / j for i, j in discrete_image_ratios]
|
| 240 |
+
diffs = [abs(w / h - r) for r in ratios]
|
| 241 |
+
best_size_idx = diffs.index(min(diffs))
|
| 242 |
+
|
| 243 |
+
return discrete_image_ratios[best_size_idx]
|
| 244 |
+
|
| 245 |
def _preprocess_continuous_image(
|
| 246 |
self,
|
| 247 |
images: list,
|
| 248 |
do_resize: bool,
|
| 249 |
size: SizeDict,
|
| 250 |
+
interpolation: Optional[F.InterpolationMode],
|
| 251 |
do_rescale: bool,
|
| 252 |
rescale_factor: float,
|
| 253 |
do_normalize: bool,
|
|
|
|
| 258 |
merge_size: int,
|
| 259 |
disable_grouping: Optional[bool],
|
| 260 |
) -> dict:
|
| 261 |
+
"""Preprocess images for continuous vision features.
|
| 262 |
|
| 263 |
+
Performs smart resize -> rescale+normalize -> patchify.
|
| 264 |
|
| 265 |
Args:
|
| 266 |
+
images: List of image tensors to preprocess.
|
| 267 |
+
do_resize: Whether to perform resizing.
|
| 268 |
+
size: SizeDict containing min_pixels/max_pixels.
|
| 269 |
+
interpolation: Interpolation method.
|
| 270 |
+
do_rescale: Whether to perform rescaling.
|
| 271 |
+
rescale_factor: Rescale factor.
|
| 272 |
+
do_normalize: Whether to perform normalization.
|
| 273 |
+
image_mean: Normalization mean.
|
| 274 |
+
image_std: Normalization standard deviation.
|
| 275 |
+
patch_size: ViT patch size.
|
| 276 |
+
temporal_patch_size: Temporal patch size.
|
| 277 |
+
merge_size: Token reduction merge size.
|
| 278 |
+
disable_grouping: Whether to disable image grouping.
|
| 279 |
|
| 280 |
Returns:
|
| 281 |
+
Dictionary with:
|
| 282 |
+
- "pixel_values": Tensor of shape (N, num_patches, patch_dim).
|
| 283 |
+
- "image_grid_thw": Tensor of shape (N, 3).
|
| 284 |
+
- "num_image_tokens": Tensor of shape (N,) with per-image token counts.
|
| 285 |
"""
|
| 286 |
# 1. Group & smart resize
|
| 287 |
grouped_images, grouped_images_index = group_images_by_shape(images, disable_grouping=disable_grouping)
|
|
|
|
| 303 |
resized_images_grouped[shape] = stacked_images
|
| 304 |
resized_images = reorder_images(resized_images_grouped, grouped_images_index)
|
| 305 |
|
| 306 |
+
# 2. Group again -> fused rescale+normalize -> patchify
|
| 307 |
grouped_images, grouped_images_index = group_images_by_shape(resized_images, disable_grouping=disable_grouping)
|
| 308 |
processed_images_grouped = {}
|
| 309 |
processed_grids = {}
|
|
|
|
| 327 |
grid_t = grid_t // temporal_patch_size
|
| 328 |
grid_h, grid_w = resized_height // patch_size, resized_width // patch_size
|
| 329 |
|
| 330 |
+
# Patchify: reshape -> permute -> flatten
|
| 331 |
patches = patches.view(
|
| 332 |
batch_size,
|
| 333 |
grid_t, temporal_patch_size,
|
|
|
|
| 362 |
self,
|
| 363 |
images: list,
|
| 364 |
original_sizes: List[Tuple[int, int]],
|
| 365 |
+
interpolation: Optional[F.InterpolationMode],
|
| 366 |
) -> dict:
|
| 367 |
+
"""Preprocess images for discrete vision tokens.
|
| 368 |
|
| 369 |
+
Resizes each image to a fixed size (discrete_image_size) and finds
|
| 370 |
+
the closest aspect ratio token.
|
| 371 |
|
| 372 |
Args:
|
| 373 |
+
images: List of image tensors to preprocess.
|
| 374 |
+
original_sizes: List of (height, width) tuples for each image.
|
| 375 |
+
interpolation: Interpolation method.
|
| 376 |
|
| 377 |
Returns:
|
| 378 |
+
Dictionary with:
|
| 379 |
+
- "discrete_pixel_values": Tensor of shape (N, C, discrete_image_size, discrete_image_size).
|
| 380 |
+
- "discrete_image_ratios": Tensor of shape (N, 2).
|
| 381 |
+
- "num_discrete_image_tokens": Tensor of shape (N,) with per-image discrete token counts.
|
| 382 |
"""
|
| 383 |
discrete_pixel_values_list = []
|
| 384 |
discrete_image_ratios_list = []
|
|
|
|
| 418 |
images: list,
|
| 419 |
do_resize: bool,
|
| 420 |
size: SizeDict,
|
| 421 |
+
interpolation: Optional[F.InterpolationMode],
|
| 422 |
do_rescale: bool,
|
| 423 |
rescale_factor: float,
|
| 424 |
do_normalize: bool,
|
|
|
|
| 430 |
disable_grouping: Optional[bool],
|
| 431 |
return_tensors: Optional[Union[str, TensorType]],
|
| 432 |
**kwargs,
|
| 433 |
+
) -> BatchFeature:
|
| 434 |
+
"""Main preprocessing entry point called by BaseImageProcessorFast.
|
| 435 |
+
|
| 436 |
+
Performs continuous image processing and optionally discrete image processing.
|
| 437 |
+
|
| 438 |
+
Args:
|
| 439 |
+
images: List of image tensors.
|
| 440 |
+
do_resize: Whether to perform resizing.
|
| 441 |
+
size: SizeDict containing min_pixels/max_pixels.
|
| 442 |
+
interpolation: Interpolation method.
|
| 443 |
+
do_rescale: Whether to perform rescaling.
|
| 444 |
+
rescale_factor: Rescale factor.
|
| 445 |
+
do_normalize: Whether to perform normalization.
|
| 446 |
+
image_mean: Normalization mean.
|
| 447 |
+
image_std: Normalization standard deviation.
|
| 448 |
+
patch_size: ViT patch size.
|
| 449 |
+
temporal_patch_size: Temporal patch size.
|
| 450 |
+
merge_size: Token reduction merge size.
|
| 451 |
+
disable_grouping: Whether to disable image grouping.
|
| 452 |
+
return_tensors: Desired tensor type for outputs.
|
| 453 |
+
|
| 454 |
+
Returns:
|
| 455 |
+
BatchFeature containing pixel_values, image_grid_thw, and optionally
|
| 456 |
+
discrete processing results.
|
| 457 |
+
"""
|
| 458 |
# Record original sizes for discrete processing before any transforms
|
| 459 |
if self.use_discrete_image_token:
|
| 460 |
original_sizes = [(img.shape[-2], img.shape[-1]) for img in images]
|
| 461 |
|
| 462 |
+
# Continuous processing
|
| 463 |
continuous_result = self._preprocess_continuous_image(
|
| 464 |
images,
|
| 465 |
do_resize=do_resize,
|
|
|
|
| 477 |
)
|
| 478 |
data = continuous_result
|
| 479 |
|
| 480 |
+
# Discrete processing
|
| 481 |
if self.use_discrete_image_token:
|
| 482 |
discrete_result = self._preprocess_discrete_image(
|
| 483 |
images,
|
|
|
|
| 488 |
|
| 489 |
return BatchFeature(data=data, tensor_type=return_tensors)
|
| 490 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 491 |
def get_num_image_tokens(
|
| 492 |
self,
|
| 493 |
image_width: Optional[int] = None,
|
| 494 |
image_height: Optional[int] = None,
|
| 495 |
+
pixel_values: Optional[torch.Tensor] = None,
|
| 496 |
include_boundary_tokens: bool = False,
|
| 497 |
min_pixels: Optional[int] = None,
|
| 498 |
max_pixels: Optional[int] = None,
|
| 499 |
patch_size: Optional[int] = None,
|
| 500 |
merge_size: Optional[int] = None,
|
| 501 |
+
return_tuple: Optional[bool] = None,
|
| 502 |
) -> int:
|
| 503 |
+
"""Compute the number of image tokens for the given input.
|
| 504 |
+
|
| 505 |
+
Args:
|
| 506 |
+
image_width: Image width (used when pixel_values is None).
|
| 507 |
+
image_height: Image height (used when pixel_values is None).
|
| 508 |
+
pixel_values: Pre-computed pixel values tensor.
|
| 509 |
+
include_boundary_tokens: Whether to include start/end boundary tokens.
|
| 510 |
+
min_pixels: Minimum pixel count. Defaults to self.min_pixels.
|
| 511 |
+
max_pixels: Maximum pixel count. Defaults to self.max_pixels.
|
| 512 |
+
patch_size: ViT patch size. Defaults to self.patch_size.
|
| 513 |
+
merge_size: Token reduction merge size. Defaults to self.merge_size.
|
| 514 |
+
return_tuple: If True, return (continuous, discrete) tuple.
|
| 515 |
+
Otherwise return the sum.
|
| 516 |
+
|
| 517 |
+
Returns:
|
| 518 |
+
Token count as int, or (continuous, discrete) tuple if return_tuple is True.
|
| 519 |
+
"""
|
| 520 |
patch_size = patch_size if patch_size is not None else self.patch_size
|
| 521 |
merge_size = merge_size if merge_size is not None else self.merge_size
|
| 522 |
min_pixels = min_pixels if min_pixels is not None else self.min_pixels
|
|
|
|
| 528 |
resized_height, resized_width = smart_resize(
|
| 529 |
image_height, image_width, factor=factor, min_pixels=min_pixels, max_pixels=max_pixels
|
| 530 |
)
|
| 531 |
+
num_patches = calculate_num_patches(resized_height, resized_width, patch_size, merge_size)
|
| 532 |
num_continuous_tokens = num_patches // (merge_size ** 2)
|
| 533 |
elif len(pixel_values.shape) == 2:
|
| 534 |
num_continuous_tokens = pixel_values.shape[0] // (merge_size ** 2)
|
|
|
|
| 537 |
pv.shape[0] // (merge_size ** 2) for pv in pixel_values
|
| 538 |
)
|
| 539 |
if include_boundary_tokens:
|
| 540 |
+
num_continuous_tokens += 2
|
| 541 |
|
| 542 |
if self.use_discrete_image_token:
|
| 543 |
discrete_token_size = self.discrete_token_size
|
| 544 |
+
num_discrete_tokens = discrete_token_size ** 2
|
|
|
|
|
|
|
| 545 |
if include_boundary_tokens:
|
| 546 |
+
num_discrete_tokens += 2
|
| 547 |
|
| 548 |
+
if return_tuple:
|
| 549 |
+
return (num_continuous_tokens, num_discrete_tokens)
|
| 550 |
+
else:
|
| 551 |
+
return num_continuous_tokens + num_discrete_tokens
|
| 552 |
|
| 553 |
def save_pretrained(
|
| 554 |
self,
|
| 555 |
save_directory: Union[str, os.PathLike],
|
| 556 |
*args,
|
| 557 |
**kwargs,
|
| 558 |
+
) -> None:
|
| 559 |
+
"""Save the processor to a directory.
|
| 560 |
+
|
| 561 |
+
Registers for auto class before saving.
|
| 562 |
+
|
| 563 |
+
Args:
|
| 564 |
+
save_directory: Directory path to save the processor.
|
| 565 |
+
"""
|
| 566 |
self.register_for_auto_class()
|
| 567 |
super().save_pretrained(save_directory, *args, **kwargs)
|
modeling_hyperclovax_omni.py
CHANGED
|
@@ -154,10 +154,6 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 154 |
else:
|
| 155 |
self.config.possible_resolutions = config.possible_resolutions
|
| 156 |
|
| 157 |
-
if without_llm:
|
| 158 |
-
# if vision_config.vision_module_type not in ["officialllava", "cream2"]:
|
| 159 |
-
# service에서, "vision_model_name_or_path" 의 경로가 vuclip_name2save_path 에 있는 default경로가 아니라, custom한 경로를 따라가야함.
|
| 160 |
-
vision_config.vison_pretrained_name_or_path = config.vision_model_name_or_path
|
| 161 |
with no_init_weights():
|
| 162 |
if self.is_qwen_visual and is_ampere_or_newer():
|
| 163 |
vision_config._attn_implementation = "flash_attention_2"
|
|
@@ -302,7 +298,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 302 |
hidden_features=input_hidden_size, # TODO: llava 처럼 hidden_size 를 input_hidden_size 가 아니라 LLM embedding size 로 바꿔주기
|
| 303 |
out_features=text_config.hidden_size,
|
| 304 |
)
|
| 305 |
-
self.
|
| 306 |
self.model_parallel = False
|
| 307 |
self.device_map = None
|
| 308 |
self.vision_model_use_no_grad = None
|
|
@@ -346,7 +342,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 346 |
) -> Union[Tuple, CausalLMOutputWithPast]:
|
| 347 |
"""
|
| 348 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 349 |
-
In positions where images are inputted, the value is replaced by config.
|
| 350 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 351 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
| 352 |
:param past_key_values: None
|
|
@@ -511,7 +507,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 511 |
):
|
| 512 |
"""
|
| 513 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 514 |
-
In positions where images are inputted, the value is replaced by config.
|
| 515 |
In cases where a sample contains no images, a single dummy image is included.
|
| 516 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 517 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
|
@@ -537,7 +533,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 537 |
else:
|
| 538 |
if self.is_qwen_visual:
|
| 539 |
inputs_embeds = self.get_input_embeddings()(input_ids)
|
| 540 |
-
context_vision_model =
|
| 541 |
|
| 542 |
if pixel_values is not None:
|
| 543 |
with context_vision_model:
|
|
@@ -545,11 +541,11 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 545 |
image_features = self.mm_projector(image_features)
|
| 546 |
|
| 547 |
if img_start_ids_list is None:
|
| 548 |
-
image_cnts = (input_ids == self.config.
|
| 549 |
else:
|
| 550 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 551 |
|
| 552 |
-
mask = input_ids.eq(self.config.
|
| 553 |
positions = mask.nonzero(as_tuple=False)
|
| 554 |
|
| 555 |
batch_idx = positions[:, 0]
|
|
@@ -564,8 +560,8 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 564 |
video_features = self.vision_model(pixel_values_videos, grid_thw=video_grid_thw)
|
| 565 |
video_features = self.mm_projector(video_features)
|
| 566 |
|
| 567 |
-
video_cnts = (input_ids == self.config.
|
| 568 |
-
mask = input_ids.eq(self.config.
|
| 569 |
positions = mask.nonzero(as_tuple=False)
|
| 570 |
|
| 571 |
batch_idx = positions[:, 0]
|
|
@@ -674,8 +670,8 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 674 |
if current_chunk_size == 0:
|
| 675 |
chunk = dummy
|
| 676 |
|
| 677 |
-
# vision 모델에 chunk를 통과시킴 (
|
| 678 |
-
if self.
|
| 679 |
# 마지막 레이어의 후처리인 post_layernorm을 Identity로 대체
|
| 680 |
self.vision_model.vision_model.post_layernorm = nn.Identity()
|
| 681 |
with context_vision_model:
|
|
@@ -684,7 +680,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 684 |
else:
|
| 685 |
with context_vision_model:
|
| 686 |
outs = self.vision_model(chunk, output_hidden_states=True)
|
| 687 |
-
outs = outs.hidden_states[self.
|
| 688 |
if self.vision_model_use_no_grad:
|
| 689 |
outs = outs.detach().requires_grad_(True)
|
| 690 |
if not is_adaptive_anyres:
|
|
@@ -728,7 +724,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 728 |
image_forward_outs = torch.cat(image_forward_outs, dim=0).to(image_forward_outs[0].dtype)
|
| 729 |
|
| 730 |
if img_start_ids_list is None:
|
| 731 |
-
image_cnts = (input_ids == self.config.
|
| 732 |
else:
|
| 733 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 734 |
|
|
@@ -781,13 +777,13 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 781 |
image_feature_dtype = image_features[0][0].dtype
|
| 782 |
|
| 783 |
if img_start_ids_list is None:
|
| 784 |
-
image_cnts = (input_ids == self.config.
|
| 785 |
else:
|
| 786 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 787 |
|
| 788 |
if non_vision_query_lengths is None:
|
| 789 |
non_vision_query_lengths = self.determine_non_vision_query_lengths(
|
| 790 |
-
input_ids, self.config.text_config.pad_token_id, self.config.
|
| 791 |
)
|
| 792 |
|
| 793 |
if vision_query_lengths is None:
|
|
@@ -832,7 +828,7 @@ class HyperCLOVAXOmniModel(HyperCLOVAXOmniPreTrainedModel):
|
|
| 832 |
] # batch_idx sample 의 첫번째 이미지 (dummy 이미지)
|
| 833 |
else:
|
| 834 |
if img_start_ids_list is None:
|
| 835 |
-
img_start_ids = (sample == self.config.
|
| 836 |
else:
|
| 837 |
img_start_ids = img_start_ids_list[batch_idx]
|
| 838 |
assert len(img_start_ids) == image_cnts[batch_idx] == len(image_features[batch_idx])
|
|
@@ -1171,7 +1167,7 @@ class HyperCLOVAXOmniForCausalLM(HyperCLOVAXOmniPreTrainedModel, GenerationMixin
|
|
| 1171 |
) -> Union[Tuple, CausalLMOutputWithPast]:
|
| 1172 |
"""
|
| 1173 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 1174 |
-
In positions where images are inputted, the value is replaced by config.
|
| 1175 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 1176 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
| 1177 |
:param past_key_values: None
|
|
@@ -1272,7 +1268,7 @@ class HyperCLOVAXOmniForCausalLM(HyperCLOVAXOmniPreTrainedModel, GenerationMixin
|
|
| 1272 |
):
|
| 1273 |
"""
|
| 1274 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 1275 |
-
In positions where images are inputted, the value is replaced by config.
|
| 1276 |
In cases where a sample contains no images, a single dummy image is included.
|
| 1277 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 1278 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
|
|
|
| 154 |
else:
|
| 155 |
self.config.possible_resolutions = config.possible_resolutions
|
| 156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 157 |
with no_init_weights():
|
| 158 |
if self.is_qwen_visual and is_ampere_or_newer():
|
| 159 |
vision_config._attn_implementation = "flash_attention_2"
|
|
|
|
| 298 |
hidden_features=input_hidden_size, # TODO: llava 처럼 hidden_size 를 input_hidden_size 가 아니라 LLM embedding size 로 바꿔주기
|
| 299 |
out_features=text_config.hidden_size,
|
| 300 |
)
|
| 301 |
+
self.vision_feature_layer = config.vision_feature_layer
|
| 302 |
self.model_parallel = False
|
| 303 |
self.device_map = None
|
| 304 |
self.vision_model_use_no_grad = None
|
|
|
|
| 342 |
) -> Union[Tuple, CausalLMOutputWithPast]:
|
| 343 |
"""
|
| 344 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 345 |
+
In positions where images are inputted, the value is replaced by config.image_token_id, which is a vocabulary index used to indicate the start of image data.
|
| 346 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 347 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
| 348 |
:param past_key_values: None
|
|
|
|
| 507 |
):
|
| 508 |
"""
|
| 509 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 510 |
+
In positions where images are inputted, the value is replaced by config.image_token_id, which is a vocabulary index used to indicate the start of image data.
|
| 511 |
In cases where a sample contains no images, a single dummy image is included.
|
| 512 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 513 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
|
|
|
| 533 |
else:
|
| 534 |
if self.is_qwen_visual:
|
| 535 |
inputs_embeds = self.get_input_embeddings()(input_ids)
|
| 536 |
+
context_vision_model = contextlib.nullcontext()
|
| 537 |
|
| 538 |
if pixel_values is not None:
|
| 539 |
with context_vision_model:
|
|
|
|
| 541 |
image_features = self.mm_projector(image_features)
|
| 542 |
|
| 543 |
if img_start_ids_list is None:
|
| 544 |
+
image_cnts = (input_ids == self.config.image_token_id).sum(dim=1).tolist()
|
| 545 |
else:
|
| 546 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 547 |
|
| 548 |
+
mask = input_ids.eq(self.config.image_token_id)
|
| 549 |
positions = mask.nonzero(as_tuple=False)
|
| 550 |
|
| 551 |
batch_idx = positions[:, 0]
|
|
|
|
| 560 |
video_features = self.vision_model(pixel_values_videos, grid_thw=video_grid_thw)
|
| 561 |
video_features = self.mm_projector(video_features)
|
| 562 |
|
| 563 |
+
video_cnts = (input_ids == self.config.video_token_id).sum(dim=1).tolist()
|
| 564 |
+
mask = input_ids.eq(self.config.video_token_id)
|
| 565 |
positions = mask.nonzero(as_tuple=False)
|
| 566 |
|
| 567 |
batch_idx = positions[:, 0]
|
|
|
|
| 670 |
if current_chunk_size == 0:
|
| 671 |
chunk = dummy
|
| 672 |
|
| 673 |
+
# vision 모델에 chunk를 통과시킴 (vision_feature_layer에 따라 처리)
|
| 674 |
+
if self.vision_feature_layer == -1:
|
| 675 |
# 마지막 레이어의 후처리인 post_layernorm을 Identity로 대체
|
| 676 |
self.vision_model.vision_model.post_layernorm = nn.Identity()
|
| 677 |
with context_vision_model:
|
|
|
|
| 680 |
else:
|
| 681 |
with context_vision_model:
|
| 682 |
outs = self.vision_model(chunk, output_hidden_states=True)
|
| 683 |
+
outs = outs.hidden_states[self.vision_feature_layer][:, visual_token_idx:]
|
| 684 |
if self.vision_model_use_no_grad:
|
| 685 |
outs = outs.detach().requires_grad_(True)
|
| 686 |
if not is_adaptive_anyres:
|
|
|
|
| 724 |
image_forward_outs = torch.cat(image_forward_outs, dim=0).to(image_forward_outs[0].dtype)
|
| 725 |
|
| 726 |
if img_start_ids_list is None:
|
| 727 |
+
image_cnts = (input_ids == self.config.image_token_id).sum(dim=1).tolist()
|
| 728 |
else:
|
| 729 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 730 |
|
|
|
|
| 777 |
image_feature_dtype = image_features[0][0].dtype
|
| 778 |
|
| 779 |
if img_start_ids_list is None:
|
| 780 |
+
image_cnts = (input_ids == self.config.image_token_id).sum(dim=1).tolist()
|
| 781 |
else:
|
| 782 |
image_cnts = [len(img_start_ids) for img_start_ids in img_start_ids_list]
|
| 783 |
|
| 784 |
if non_vision_query_lengths is None:
|
| 785 |
non_vision_query_lengths = self.determine_non_vision_query_lengths(
|
| 786 |
+
input_ids, self.config.text_config.pad_token_id, self.config.image_token_id
|
| 787 |
)
|
| 788 |
|
| 789 |
if vision_query_lengths is None:
|
|
|
|
| 828 |
] # batch_idx sample 의 첫번째 이미지 (dummy 이미지)
|
| 829 |
else:
|
| 830 |
if img_start_ids_list is None:
|
| 831 |
+
img_start_ids = (sample == self.config.image_token_id).nonzero()
|
| 832 |
else:
|
| 833 |
img_start_ids = img_start_ids_list[batch_idx]
|
| 834 |
assert len(img_start_ids) == image_cnts[batch_idx] == len(image_features[batch_idx])
|
|
|
|
| 1167 |
) -> Union[Tuple, CausalLMOutputWithPast]:
|
| 1168 |
"""
|
| 1169 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 1170 |
+
In positions where images are inputted, the value is replaced by config.image_token_id, which is a vocabulary index used to indicate the start of image data.
|
| 1171 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 1172 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
| 1173 |
:param past_key_values: None
|
|
|
|
| 1268 |
):
|
| 1269 |
"""
|
| 1270 |
:param input_ids: torch.int64 : torch.size([batchsize, variable)]) : SystemPrompt with Question text token indices for tokenizer.
|
| 1271 |
+
In positions where images are inputted, the value is replaced by config.image_token_id, which is a vocabulary index used to indicate the start of image data.
|
| 1272 |
In cases where a sample contains no images, a single dummy image is included.
|
| 1273 |
:param pixel_values: List of List of 4D tensor (torch.float32)
|
| 1274 |
Each outer list corresponds to a batch and contains inner lists, each holding tensors for images in a sample. The structure accounts for samples with multiple images.
|
preprocessor_config.json
CHANGED
|
@@ -78,7 +78,7 @@
|
|
| 78 |
"video_do_resize": true,
|
| 79 |
"video_end_token": "<|video_end|>",
|
| 80 |
"video_max_frames": 120,
|
| 81 |
-
"video_max_pixels":
|
| 82 |
"video_mean": [
|
| 83 |
0.48145466,
|
| 84 |
0.4578275,
|
|
|
|
| 78 |
"video_do_resize": true,
|
| 79 |
"video_end_token": "<|video_end|>",
|
| 80 |
"video_max_frames": 120,
|
| 81 |
+
"video_max_pixels": 12845056,
|
| 82 |
"video_mean": [
|
| 83 |
0.48145466,
|
| 84 |
0.4578275,
|
processing_hyperclovax_omni.py
CHANGED
|
@@ -833,24 +833,7 @@ class HyperCLOVAXOmniProcessor(ProcessorMixin):
|
|
| 833 |
and self.image_processor.use_discrete_image_token
|
| 834 |
):
|
| 835 |
data.update(discrete_image_inputs)
|
| 836 |
-
|
| 837 |
-
# _tensorable_data, _untensorable_data = dict(), dict()
|
| 838 |
-
# for _k, _v in data.items():
|
| 839 |
-
# if _v is None:
|
| 840 |
-
# continue
|
| 841 |
-
# if isinstance(_v, list) and any(x is None for x in _v):
|
| 842 |
-
# continue
|
| 843 |
-
# if _k in [
|
| 844 |
-
# "discrete_image_ratios",
|
| 845 |
-
# "num_audio_tokens",
|
| 846 |
-
# "num_discrete_audio_tokens",
|
| 847 |
-
# ]:
|
| 848 |
-
# _untensorable_data[_k] = _v
|
| 849 |
-
# else:
|
| 850 |
-
# _tensorable_data[_k] = _v
|
| 851 |
-
|
| 852 |
-
# model_inputs = BatchFeature(data=_tensorable_data, tensor_type=return_tensors)
|
| 853 |
-
# model_inputs.update(_untensorable_data)
|
| 854 |
model_inputs = BatchFeature(data=data, tensor_type=return_tensors)
|
| 855 |
return model_inputs
|
| 856 |
|
|
@@ -860,143 +843,159 @@ class HyperCLOVAXOmniProcessor(ProcessorMixin):
|
|
| 860 |
):
|
| 861 |
audio_placeholder = ""
|
| 862 |
if self.audio_processor.use_discrete_audio_token:
|
| 863 |
-
audio_placeholder += f'{self.audio_processor.discrete_audio_start_token}{self.audio_processor.discrete_audio_token}{self.audio_processor.discrete_audio_end_token}'
|
| 864 |
audio_placeholder += f'{self.audio_processor.audio_start_token}{self.audio_processor.audio_token}{self.audio_processor.audio_end_token}'
|
| 865 |
if tokenize:
|
| 866 |
audio_placeholder = self.tokenizer.encode(audio_placeholder)
|
| 867 |
return audio_placeholder
|
| 868 |
|
| 869 |
-
def get_image_placeholder(
|
| 870 |
-
self,
|
| 871 |
-
tokenize: bool = False,
|
| 872 |
-
):
|
| 873 |
-
image_placeholder = ""
|
| 874 |
-
if self.image_processor.use_discrete_audio_token:
|
| 875 |
-
image_placeholder += f'{self.image_processor.discrete_image_start_token}{self.image_processor.discrete_image_token}{self.image_processor.discrete_image_end_token}'
|
| 876 |
-
image_placeholder += f'{self.image_processor.image_start_token}{self.image_processor.image_token}{self.image_processor.image_end_token}'
|
| 877 |
-
if tokenize:
|
| 878 |
-
image_placeholder = self.tokenizer.encode(image_placeholder)
|
| 879 |
-
return image_placeholder
|
| 880 |
-
|
| 881 |
-
def get_video_placeholder(
|
| 882 |
-
self,
|
| 883 |
-
tokenize: bool = False,
|
| 884 |
-
):
|
| 885 |
-
video_placeholder = f'{self.video_processor.video_start_token}{self.video_processor.video_token}{self.video_processor.video_end_token}'
|
| 886 |
-
if tokenize:
|
| 887 |
-
video_placeholder = self.tokenizer.encode(video_placeholder)
|
| 888 |
-
return video_placeholder
|
| 889 |
-
|
| 890 |
def get_audio_token_replacement(
|
| 891 |
self,
|
| 892 |
num_audio_tokens: int,
|
|
|
|
| 893 |
include_boundary_tokens: Optional[bool] = False,
|
| 894 |
tokenize: Optional[bool] = False,
|
|
|
|
| 895 |
):
|
|
|
|
|
|
|
| 896 |
if (
|
| 897 |
isinstance(num_audio_tokens, (list, tuple))
|
| 898 |
or (isinstance(num_audio_tokens, torch.Tensor) and num_audio_tokens.dim() >= 1)
|
| 899 |
):
|
| 900 |
num_audio_tokens = num_audio_tokens[0]
|
| 901 |
-
|
| 902 |
-
replacement = self.audio_processor.audio_token * num_audio_tokens
|
| 903 |
if include_boundary_tokens:
|
| 904 |
-
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
|
| 909 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 910 |
self,
|
| 911 |
-
|
| 912 |
-
include_boundary_tokens: Optional[bool] = False,
|
| 913 |
-
tokenize: Optional[bool] = False,
|
| 914 |
):
|
| 915 |
-
|
| 916 |
-
|
| 917 |
-
|
| 918 |
-
|
| 919 |
-
num_discrete_audio_tokens = num_discrete_audio_tokens[0]
|
| 920 |
-
|
| 921 |
-
replacement = self.audio_processor.discrete_audio_token * num_discrete_audio_tokens
|
| 922 |
-
if include_boundary_tokens:
|
| 923 |
-
replacement = f"{self.audio_processor.discrete_audio_start_token}{replacement}{self.audio_processor.discrete_audio_end_token}"
|
| 924 |
if tokenize:
|
| 925 |
-
|
| 926 |
-
return
|
| 927 |
|
| 928 |
def get_image_token_replacement(
|
| 929 |
self,
|
| 930 |
num_image_tokens: int,
|
|
|
|
| 931 |
include_boundary_tokens: Optional[bool] = False,
|
| 932 |
tokenize: Optional[bool] = False,
|
|
|
|
| 933 |
):
|
|
|
|
|
|
|
| 934 |
if (
|
| 935 |
isinstance(num_image_tokens, (list, tuple))
|
| 936 |
or (isinstance(num_image_tokens, torch.Tensor) and num_image_tokens.dim() >= 1)
|
| 937 |
):
|
| 938 |
num_image_tokens = num_image_tokens[0]
|
| 939 |
-
|
| 940 |
discrete_token_size = self.image_processor.discrete_token_size
|
| 941 |
-
|
| 942 |
if include_boundary_tokens:
|
| 943 |
-
|
| 944 |
-
|
| 945 |
-
|
| 946 |
-
|
| 947 |
-
|
| 948 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 949 |
self,
|
| 950 |
-
|
| 951 |
-
include_boundary_tokens: Optional[bool] = False,
|
| 952 |
-
tokenize: Optional[bool] = False,
|
| 953 |
):
|
| 954 |
-
|
| 955 |
-
discrete_image_ratio
|
| 956 |
-
and len(discrete_image_ratio) == 1
|
| 957 |
-
and (
|
| 958 |
-
isinstance(discrete_image_ratio, (list, tuple))
|
| 959 |
-
or (isinstance(discrete_image_ratio, torch.Tensor) and discrete_image_ratio.dim() >= 2)
|
| 960 |
-
)
|
| 961 |
-
): # [[16, 9]], or torch.Tensor([[16, 9]])
|
| 962 |
-
discrete_image_ratio = discrete_image_ratio[0]
|
| 963 |
-
|
| 964 |
-
row_str = self.image_processor.discrete_image_token * self.image_processor.discrete_token_size
|
| 965 |
-
# row_str += self.image_processor.vision_eol_token
|
| 966 |
-
replacement = row_str * self.image_processor.discrete_token_size
|
| 967 |
-
if discrete_image_ratio:
|
| 968 |
-
if isinstance(discrete_image_ratio, (list, tuple)):
|
| 969 |
-
ratio_key = f"{int(discrete_image_ratio[0])}:{int(discrete_image_ratio[1])}"
|
| 970 |
-
elif isinstance(discrete_image_ratio, torch.Tensor):
|
| 971 |
-
ratio_key = f"{discrete_image_ratio[0].item()}:{discrete_image_ratio[1].item()}"
|
| 972 |
-
discrete_image_ratio_token = self.image_processor.discrete_image_ratio_tokens[ratio_key]
|
| 973 |
-
replacement = f"{discrete_image_ratio_token}{replacement}"
|
| 974 |
-
# replacement = f"{replacement}{self.image_processor.vision_eof_token}"
|
| 975 |
-
if include_boundary_tokens:
|
| 976 |
-
replacement = f"{self.image_processor.discrete_image_start_token}{replacement}{self.image_processor.discrete_image_end_token}"
|
| 977 |
if tokenize:
|
| 978 |
-
|
| 979 |
-
return
|
| 980 |
|
| 981 |
def get_video_token_replacement(
|
| 982 |
self,
|
| 983 |
num_video_tokens: int,
|
| 984 |
include_boundary_tokens: Optional[bool] = False,
|
| 985 |
tokenize: Optional[bool] = False,
|
|
|
|
| 986 |
):
|
|
|
|
|
|
|
| 987 |
if (
|
| 988 |
isinstance(num_video_tokens, (list, tuple))
|
| 989 |
or (isinstance(num_video_tokens, torch.Tensor) and num_video_tokens.dim() >= 1)
|
| 990 |
):
|
| 991 |
num_video_tokens = num_video_tokens[0]
|
| 992 |
-
|
| 993 |
merge_length = self.video_processor.video_merge_size**2
|
| 994 |
-
|
| 995 |
if include_boundary_tokens:
|
| 996 |
-
|
| 997 |
-
|
| 998 |
-
|
| 999 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1000 |
|
| 1001 |
def _interleave_video_audio_tokens(
|
| 1002 |
self,
|
|
|
|
| 833 |
and self.image_processor.use_discrete_image_token
|
| 834 |
):
|
| 835 |
data.update(discrete_image_inputs)
|
| 836 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 837 |
model_inputs = BatchFeature(data=data, tensor_type=return_tensors)
|
| 838 |
return model_inputs
|
| 839 |
|
|
|
|
| 843 |
):
|
| 844 |
audio_placeholder = ""
|
| 845 |
if self.audio_processor.use_discrete_audio_token:
|
| 846 |
+
audio_placeholder += f'{self.audio_processor.discrete_audio_start_token}{self.audio_processor.discrete_audio_token}{self.audio_processor.discrete_audio_end_token}\n'
|
| 847 |
audio_placeholder += f'{self.audio_processor.audio_start_token}{self.audio_processor.audio_token}{self.audio_processor.audio_end_token}'
|
| 848 |
if tokenize:
|
| 849 |
audio_placeholder = self.tokenizer.encode(audio_placeholder)
|
| 850 |
return audio_placeholder
|
| 851 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 852 |
def get_audio_token_replacement(
|
| 853 |
self,
|
| 854 |
num_audio_tokens: int,
|
| 855 |
+
num_discrete_audio_tokens: Optional[int] = None,
|
| 856 |
include_boundary_tokens: Optional[bool] = False,
|
| 857 |
tokenize: Optional[bool] = False,
|
| 858 |
+
return_tuple: Optional[bool] = None,
|
| 859 |
):
|
| 860 |
+
conitnuous_replacement, discrete_replacement = "", ""
|
| 861 |
+
|
| 862 |
if (
|
| 863 |
isinstance(num_audio_tokens, (list, tuple))
|
| 864 |
or (isinstance(num_audio_tokens, torch.Tensor) and num_audio_tokens.dim() >= 1)
|
| 865 |
):
|
| 866 |
num_audio_tokens = num_audio_tokens[0]
|
| 867 |
+
conitnuous_replacement = self.audio_processor.audio_token * num_audio_tokens
|
|
|
|
| 868 |
if include_boundary_tokens:
|
| 869 |
+
conitnuous_replacement = f"{self.audio_processor.audio_start_token}{conitnuous_replacement}{self.audio_processor.audio_end_token}"
|
| 870 |
+
|
| 871 |
+
if self.audio_processor.use_discrete_audio_token:
|
| 872 |
+
if (
|
| 873 |
+
isinstance(num_discrete_audio_tokens, (list, tuple))
|
| 874 |
+
or (isinstance(num_discrete_audio_tokens, torch.Tensor) and num_discrete_audio_tokens.dim() >= 1)
|
| 875 |
+
):
|
| 876 |
+
num_discrete_audio_tokens = num_discrete_audio_tokens[0]
|
| 877 |
+
discrete_replacement = self.audio_processor.discrete_audio_token * num_discrete_audio_tokens
|
| 878 |
+
if include_boundary_tokens:
|
| 879 |
+
discrete_replacement = f"{self.audio_processor.discrete_audio_start_token}{discrete_replacement}{self.audio_processor.discrete_audio_end_token}"
|
| 880 |
+
discrete_replacement = f'{discrete_replacement}\n'
|
| 881 |
+
|
| 882 |
+
if return_tuple:
|
| 883 |
+
if tokenize:
|
| 884 |
+
conitnuous_replacement = self.tokenizer.encode(conitnuous_replacement)
|
| 885 |
+
discrete_replacement = self.tokenizer.encode(discrete_replacement)
|
| 886 |
+
return (conitnuous_replacement, discrete_replacement)
|
| 887 |
+
else:
|
| 888 |
+
replacement = f'{discrete_replacement}{conitnuous_replacement}'
|
| 889 |
+
if tokenize:
|
| 890 |
+
replacement = self.tokenizer.encode(replacement)
|
| 891 |
+
return replacement
|
| 892 |
+
|
| 893 |
+
def get_image_placeholder(
|
| 894 |
self,
|
| 895 |
+
tokenize: bool = False,
|
|
|
|
|
|
|
| 896 |
):
|
| 897 |
+
image_placeholder = ""
|
| 898 |
+
if self.image_processor.use_discrete_audio_token:
|
| 899 |
+
image_placeholder += f'{self.image_processor.discrete_image_start_token}{self.image_processor.discrete_image_token}{self.image_processor.discrete_image_end_token}\n'
|
| 900 |
+
image_placeholder += f'{self.image_processor.image_start_token}{self.image_processor.image_token}{self.image_processor.image_end_token}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 901 |
if tokenize:
|
| 902 |
+
image_placeholder = self.tokenizer.encode(image_placeholder)
|
| 903 |
+
return image_placeholder
|
| 904 |
|
| 905 |
def get_image_token_replacement(
|
| 906 |
self,
|
| 907 |
num_image_tokens: int,
|
| 908 |
+
discrete_image_ratio: Optional[List[int]] = None,
|
| 909 |
include_boundary_tokens: Optional[bool] = False,
|
| 910 |
tokenize: Optional[bool] = False,
|
| 911 |
+
return_tuple: Optional[bool] = None,
|
| 912 |
):
|
| 913 |
+
conitnuous_replacement, discrete_replacement = "", ""
|
| 914 |
+
|
| 915 |
if (
|
| 916 |
isinstance(num_image_tokens, (list, tuple))
|
| 917 |
or (isinstance(num_image_tokens, torch.Tensor) and num_image_tokens.dim() >= 1)
|
| 918 |
):
|
| 919 |
num_image_tokens = num_image_tokens[0]
|
|
|
|
| 920 |
discrete_token_size = self.image_processor.discrete_token_size
|
| 921 |
+
continuous_replacement = self.image_processor.image_token * num_image_tokens
|
| 922 |
if include_boundary_tokens:
|
| 923 |
+
continuous_replacement = f"{self.image_processor.image_start_token}{continuous_replacement}{self.image_processor.image_end_token}"
|
| 924 |
+
|
| 925 |
+
if self.image_processor.use_discrete_image_token:
|
| 926 |
+
if (
|
| 927 |
+
discrete_image_ratio
|
| 928 |
+
and len(discrete_image_ratio) == 1
|
| 929 |
+
and (
|
| 930 |
+
isinstance(discrete_image_ratio, (list, tuple))
|
| 931 |
+
or (isinstance(discrete_image_ratio, torch.Tensor) and discrete_image_ratio.dim() >= 2)
|
| 932 |
+
)
|
| 933 |
+
): # [[16, 9]], or torch.Tensor([[16, 9]])
|
| 934 |
+
discrete_image_ratio = discrete_image_ratio[0]
|
| 935 |
+
row_str = self.image_processor.discrete_image_token * self.image_processor.discrete_token_size
|
| 936 |
+
# row_str += self.image_processor.vision_eol_token
|
| 937 |
+
discrete_replacement = row_str * self.image_processor.discrete_token_size
|
| 938 |
+
if discrete_image_ratio:
|
| 939 |
+
if isinstance(discrete_image_ratio, (list, tuple)):
|
| 940 |
+
ratio_key = f"{int(discrete_image_ratio[0])}:{int(discrete_image_ratio[1])}"
|
| 941 |
+
elif isinstance(discrete_image_ratio, torch.Tensor):
|
| 942 |
+
ratio_key = f"{discrete_image_ratio[0].item()}:{discrete_image_ratio[1].item()}"
|
| 943 |
+
discrete_image_ratio_token = self.image_processor.discrete_image_ratio_tokens[ratio_key]
|
| 944 |
+
discrete_replacement = f"{discrete_image_ratio_token}{discrete_replacement}"
|
| 945 |
+
# discrete_replacement = f"{discrete_replacement}{self.image_processor.vision_eof_token}"
|
| 946 |
+
if include_boundary_tokens:
|
| 947 |
+
discrete_replacement = f"{self.image_processor.discrete_image_start_token}{discrete_replacement}{self.image_processor.discrete_image_end_token}"
|
| 948 |
+
discrete_replacement = f'{discrete_replacement}\n'
|
| 949 |
+
|
| 950 |
+
if return_tuple:
|
| 951 |
+
if tokenize:
|
| 952 |
+
conitnuous_replacement = self.tokenizer.encode(conitnuous_replacement)
|
| 953 |
+
discrete_replacement = self.tokenizer.encode(discrete_replacement)
|
| 954 |
+
return (conitnuous_replacement, discrete_replacement)
|
| 955 |
+
else:
|
| 956 |
+
replacement = f'{discrete_replacement}{conitnuous_replacement}'
|
| 957 |
+
if tokenize:
|
| 958 |
+
replacement = self.tokenizer.encode(replacement)
|
| 959 |
+
return replacement
|
| 960 |
+
|
| 961 |
+
def get_video_placeholder(
|
| 962 |
self,
|
| 963 |
+
tokenize: bool = False,
|
|
|
|
|
|
|
| 964 |
):
|
| 965 |
+
video_placeholder = f'{self.video_processor.video_start_token}{self.video_processor.video_token}{self.video_processor.video_end_token}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 966 |
if tokenize:
|
| 967 |
+
video_placeholder = self.tokenizer.encode(video_placeholder)
|
| 968 |
+
return video_placeholder
|
| 969 |
|
| 970 |
def get_video_token_replacement(
|
| 971 |
self,
|
| 972 |
num_video_tokens: int,
|
| 973 |
include_boundary_tokens: Optional[bool] = False,
|
| 974 |
tokenize: Optional[bool] = False,
|
| 975 |
+
return_tuple: Optional[bool] = None,
|
| 976 |
):
|
| 977 |
+
conitnuous_replacement, discrete_replacement = "", ""
|
| 978 |
+
|
| 979 |
if (
|
| 980 |
isinstance(num_video_tokens, (list, tuple))
|
| 981 |
or (isinstance(num_video_tokens, torch.Tensor) and num_video_tokens.dim() >= 1)
|
| 982 |
):
|
| 983 |
num_video_tokens = num_video_tokens[0]
|
|
|
|
| 984 |
merge_length = self.video_processor.video_merge_size**2
|
| 985 |
+
conitnuous_replacement = self.video_processor.video_token * int(num_video_tokens)
|
| 986 |
if include_boundary_tokens:
|
| 987 |
+
conitnuous_replacement = f"{self.video_processor.video_start_token}{conitnuous_replacement}{self.video_processor.video_end_token}"
|
| 988 |
+
|
| 989 |
+
if return_tuple:
|
| 990 |
+
if tokenize:
|
| 991 |
+
conitnuous_replacement = self.tokenizer.encode(conitnuous_replacement)
|
| 992 |
+
discrete_replacement = self.tokenizer.encode(discrete_replacement)
|
| 993 |
+
return (conitnuous_replacement, discrete_replacement)
|
| 994 |
+
else:
|
| 995 |
+
replacement = f'{discrete_replacement}{conitnuous_replacement}'
|
| 996 |
+
if tokenize:
|
| 997 |
+
replacement = self.tokenizer.encode(replacement)
|
| 998 |
+
return replacement
|
| 999 |
|
| 1000 |
def _interleave_video_audio_tokens(
|
| 1001 |
self,
|
tokenizer.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:25be15af870991ef21ee479f5ca5f72ab4160e51e6e6a6131b65505ec32b63c4
|
| 3 |
+
size 23621753
|
tokenizer_config.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:7fa862c7a52c316ae1c3e81d74f36688d970eb56a367957473bf185eff64a259
|
| 3 |
+
size 13220251
|
video_processing_hyperclovax_omni.py
CHANGED
|
@@ -1,46 +1,61 @@
|
|
| 1 |
"""
|
| 2 |
-
|
| 3 |
|
| 4 |
-
|
| 5 |
-
- Smart resize:
|
| 6 |
-
- Temporal patch:
|
| 7 |
-
- Patch flattening:
|
| 8 |
|
| 9 |
-
BaseVideoProcessor
|
| 10 |
-
Track A (Qwen2VLVideoProcessor)와 bit-perfect 일치를 달성합니다.
|
| 11 |
-
|
| 12 |
-
입력 준비(numpy→torch), kwargs 해석, resample→interpolation 변환 등은
|
| 13 |
-
BaseVideoProcessor.preprocess()와 동일한 흐름을 따릅니다.
|
| 14 |
-
_preprocess_continuous_video는 Qwen2VLVideoProcessor._preprocess와
|
| 15 |
-
동일한 시그니처·로직을 사용합니다.
|
| 16 |
"""
|
| 17 |
|
| 18 |
import math
|
|
|
|
|
|
|
| 19 |
import numpy as np
|
| 20 |
import torch
|
| 21 |
-
from
|
| 22 |
-
|
| 23 |
from transformers.image_processing_utils import BatchFeature
|
|
|
|
| 24 |
from transformers.image_transforms import to_channel_dimension_format
|
| 25 |
from transformers.image_utils import (
|
| 26 |
OPENAI_CLIP_MEAN,
|
| 27 |
OPENAI_CLIP_STD,
|
| 28 |
-
PILImageResampling,
|
| 29 |
ChannelDimension,
|
| 30 |
-
|
| 31 |
SizeDict,
|
|
|
|
| 32 |
)
|
|
|
|
| 33 |
from transformers.utils import TensorType, logging
|
| 34 |
from transformers.video_processing_utils import BaseVideoProcessor
|
| 35 |
from transformers.video_utils import group_videos_by_shape, reorder_videos
|
| 36 |
-
from transformers.processing_utils import VideosKwargs
|
| 37 |
|
| 38 |
logger = logging.get_logger(__name__)
|
| 39 |
|
| 40 |
|
| 41 |
def smart_resize(
|
| 42 |
-
height: int,
|
| 43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
if max(height, width) / min(height, width) > 200:
|
| 45 |
raise ValueError(
|
| 46 |
f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}"
|
|
@@ -82,11 +97,10 @@ class HyperCLOVAXOmniVideosKwargs(VideosKwargs, total=False):
|
|
| 82 |
|
| 83 |
|
| 84 |
class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
| 85 |
-
"""
|
| 86 |
-
Video processor for HyperCLOVAXOmni that follows Qwen2VL's video processing logic.
|
| 87 |
|
| 88 |
-
|
| 89 |
-
|
| 90 |
"""
|
| 91 |
|
| 92 |
model_input_names = ["pixel_values_videos", "video_grid_thw"]
|
|
@@ -117,7 +131,7 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 117 |
vision_eof_token: str = "<|vision_eof|>",
|
| 118 |
**kwargs,
|
| 119 |
):
|
| 120 |
-
#
|
| 121 |
size = {"shortest_edge": video_min_pixels, "longest_edge": video_max_pixels}
|
| 122 |
|
| 123 |
super().__init__(
|
|
@@ -149,10 +163,10 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 149 |
|
| 150 |
def _preprocess_continuous_video(
|
| 151 |
self,
|
| 152 |
-
videos: List[
|
| 153 |
do_resize: bool,
|
| 154 |
size: SizeDict,
|
| 155 |
-
interpolation:
|
| 156 |
do_rescale: bool,
|
| 157 |
rescale_factor: float,
|
| 158 |
do_normalize: bool,
|
|
@@ -161,33 +175,31 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 161 |
patch_size: int,
|
| 162 |
temporal_patch_size: int,
|
| 163 |
merge_size: int,
|
| 164 |
-
) ->
|
| 165 |
-
"""
|
| 166 |
|
| 167 |
-
|
| 168 |
-
group_videos_by_shape → self.resize (torchvision) → self.rescale_and_normalize → patchify
|
| 169 |
|
| 170 |
Args:
|
| 171 |
-
videos: channel-first torch
|
| 172 |
-
do_resize:
|
| 173 |
-
size: SizeDict with shortest_edge
|
| 174 |
interpolation: torchvision InterpolationMode.
|
| 175 |
-
do_rescale:
|
| 176 |
-
rescale_factor:
|
| 177 |
-
do_normalize:
|
| 178 |
-
image_mean:
|
| 179 |
-
image_std:
|
| 180 |
-
patch_size: ViT patch
|
| 181 |
-
temporal_patch_size:
|
| 182 |
-
merge_size:
|
| 183 |
|
| 184 |
Returns:
|
| 185 |
-
|
| 186 |
-
- "pixel_values_videos": (grid_t * grid_h * grid_w, feat_dim)
|
| 187 |
-
- "video_grid_thw": [grid_t, grid_h, grid_w]
|
| 188 |
-
- "num_video_tokens":
|
| 189 |
"""
|
| 190 |
-
# --- Qwen2VLVideoProcessor._preprocess와 동일한 흐름 ---
|
| 191 |
grouped_videos, grouped_videos_index = group_videos_by_shape(videos)
|
| 192 |
|
| 193 |
resized_videos_grouped = {}
|
|
@@ -258,11 +270,15 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 258 |
"num_video_tokens": num_video_tokens,
|
| 259 |
}
|
| 260 |
|
| 261 |
-
def _preprocess_discrete_video(
|
| 262 |
-
|
| 263 |
-
|
| 264 |
-
|
| 265 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 266 |
return {}
|
| 267 |
|
| 268 |
def preprocess(
|
|
@@ -271,28 +287,29 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 271 |
return_tensors: Optional[Union[str, TensorType]] = None,
|
| 272 |
**kwargs,
|
| 273 |
) -> BatchFeature:
|
| 274 |
-
"""
|
| 275 |
|
| 276 |
-
BaseVideoProcessor.preprocess()
|
| 277 |
-
1. numpy
|
| 278 |
-
2. kwargs
|
| 279 |
-
3. _preprocess_continuous_video
|
| 280 |
|
| 281 |
Args:
|
| 282 |
-
videos:
|
| 283 |
-
- np.ndarray:
|
| 284 |
-
- List[np.ndarray]:
|
|
|
|
| 285 |
|
| 286 |
Returns:
|
| 287 |
BatchFeature with:
|
| 288 |
-
- pixel_values_videos: (total_patches, feat_dim)
|
| 289 |
-
- video_grid_thw: (num_videos, 3)
|
| 290 |
-
- num_video_tokens: (num_videos,)
|
| 291 |
"""
|
| 292 |
if isinstance(videos, np.ndarray) and videos.ndim == 4:
|
| 293 |
videos = [videos]
|
| 294 |
|
| 295 |
-
#
|
| 296 |
do_resize = kwargs.pop("do_resize", kwargs.pop("video_do_resize", None))
|
| 297 |
if do_resize is None:
|
| 298 |
do_resize = self.do_resize
|
|
@@ -337,7 +354,7 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 337 |
if merge_size is None:
|
| 338 |
merge_size = self.video_merge_size
|
| 339 |
|
| 340 |
-
#
|
| 341 |
min_pixels = kwargs.pop("min_pixels", kwargs.pop("video_min_pixels", None))
|
| 342 |
if min_pixels is None:
|
| 343 |
min_pixels = self.size["shortest_edge"]
|
|
@@ -348,8 +365,7 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 348 |
|
| 349 |
size = SizeDict(shortest_edge=min_pixels, longest_edge=max_pixels)
|
| 350 |
|
| 351 |
-
#
|
| 352 |
-
from transformers.image_processing_utils_fast import pil_torch_interpolation_mapping
|
| 353 |
if isinstance(resample, (PILImageResampling, int)):
|
| 354 |
interpolation = pil_torch_interpolation_mapping[resample]
|
| 355 |
else:
|
|
@@ -360,18 +376,17 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 360 |
if isinstance(image_std, list):
|
| 361 |
image_std = tuple(image_std)
|
| 362 |
|
| 363 |
-
#
|
| 364 |
pixel_values_list = []
|
| 365 |
grid_thw_list = []
|
| 366 |
num_video_tokens_list = []
|
| 367 |
|
| 368 |
for video in videos:
|
| 369 |
-
#
|
| 370 |
if isinstance(video, np.ndarray):
|
| 371 |
video = to_channel_dimension_format(video, ChannelDimension.FIRST)
|
| 372 |
video = torch.from_numpy(video).contiguous()
|
| 373 |
|
| 374 |
-
# convert_to_rgb: BaseVideoProcessor.convert_to_rgb (torchvision 기반)
|
| 375 |
if do_convert_rgb:
|
| 376 |
video = self.convert_to_rgb(video)
|
| 377 |
|
|
@@ -406,15 +421,34 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 406 |
image_width: Optional[int] = None,
|
| 407 |
image_height: Optional[int] = None,
|
| 408 |
num_frames: Optional[int] = None,
|
| 409 |
-
pixel_values_videos: Optional[
|
| 410 |
include_boundary_tokens: bool = False,
|
| 411 |
patch_size: Optional[int] = None,
|
| 412 |
temporal_patch_size: Optional[int] = None,
|
| 413 |
merge_size: Optional[int] = None,
|
| 414 |
min_pixels: Optional[int] = None,
|
| 415 |
max_pixels: Optional[int] = None,
|
| 416 |
-
|
| 417 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 418 |
patch_size = patch_size if patch_size is not None else self.video_patch_size
|
| 419 |
temporal_patch_size = temporal_patch_size if temporal_patch_size is not None else self.video_temporal_patch_size
|
| 420 |
merge_size = merge_size if merge_size is not None else self.video_merge_size
|
|
@@ -440,4 +474,7 @@ class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
|
| 440 |
if include_boundary_tokens:
|
| 441 |
num_continuous_tokens += 2
|
| 442 |
|
| 443 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
"""
|
| 2 |
+
HyperCLOVAX Omni Video Processor
|
| 3 |
|
| 4 |
+
Implements dynamic resolution video processing:
|
| 5 |
+
- Smart resize: adjusts video frames to fit within min_pixels and max_pixels
|
| 6 |
+
- Temporal patch: frame grouping by temporal_patch_size
|
| 7 |
+
- Patch flattening: token reduction using merge_size
|
| 8 |
|
| 9 |
+
Based on BaseVideoProcessor with torchvision resize.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
"""
|
| 11 |
|
| 12 |
import math
|
| 13 |
+
from typing import Dict, List, Optional, Tuple, Union
|
| 14 |
+
|
| 15 |
import numpy as np
|
| 16 |
import torch
|
| 17 |
+
from torchvision.transforms.v2 import functional as F
|
|
|
|
| 18 |
from transformers.image_processing_utils import BatchFeature
|
| 19 |
+
from transformers.image_processing_utils_fast import pil_torch_interpolation_mapping
|
| 20 |
from transformers.image_transforms import to_channel_dimension_format
|
| 21 |
from transformers.image_utils import (
|
| 22 |
OPENAI_CLIP_MEAN,
|
| 23 |
OPENAI_CLIP_STD,
|
|
|
|
| 24 |
ChannelDimension,
|
| 25 |
+
PILImageResampling,
|
| 26 |
SizeDict,
|
| 27 |
+
get_image_size,
|
| 28 |
)
|
| 29 |
+
from transformers.processing_utils import VideosKwargs
|
| 30 |
from transformers.utils import TensorType, logging
|
| 31 |
from transformers.video_processing_utils import BaseVideoProcessor
|
| 32 |
from transformers.video_utils import group_videos_by_shape, reorder_videos
|
|
|
|
| 33 |
|
| 34 |
logger = logging.get_logger(__name__)
|
| 35 |
|
| 36 |
|
| 37 |
def smart_resize(
|
| 38 |
+
height: int,
|
| 39 |
+
width: int,
|
| 40 |
+
factor: int = 28,
|
| 41 |
+
min_pixels: int = 56 * 56,
|
| 42 |
+
max_pixels: int = 14 * 14 * 4 * 1280,
|
| 43 |
+
) -> Tuple[int, int]:
|
| 44 |
+
"""Smart resize for dynamic resolution.
|
| 45 |
+
|
| 46 |
+
Adjusts dimensions so that both sides are divisible by factor
|
| 47 |
+
and total pixel count is between min_pixels and max_pixels.
|
| 48 |
+
|
| 49 |
+
Args:
|
| 50 |
+
height: Original height.
|
| 51 |
+
width: Original width.
|
| 52 |
+
factor: Rounding unit (default: 28 = patch_size * merge_size).
|
| 53 |
+
min_pixels: Minimum pixel count.
|
| 54 |
+
max_pixels: Maximum pixel count.
|
| 55 |
+
|
| 56 |
+
Returns:
|
| 57 |
+
Tuple of (new_height, new_width).
|
| 58 |
+
"""
|
| 59 |
if max(height, width) / min(height, width) > 200:
|
| 60 |
raise ValueError(
|
| 61 |
f"absolute aspect ratio must be smaller than 200, got {max(height, width) / min(height, width)}"
|
|
|
|
| 97 |
|
| 98 |
|
| 99 |
class HyperCLOVAXOmniVideoProcessor(BaseVideoProcessor):
|
| 100 |
+
"""Video processor for HyperCLOVAX Omni.
|
|
|
|
| 101 |
|
| 102 |
+
Uses torchvision resize and rescale_and_normalize for
|
| 103 |
+
dynamic resolution video processing.
|
| 104 |
"""
|
| 105 |
|
| 106 |
model_input_names = ["pixel_values_videos", "video_grid_thw"]
|
|
|
|
| 131 |
vision_eof_token: str = "<|vision_eof|>",
|
| 132 |
**kwargs,
|
| 133 |
):
|
| 134 |
+
# Construct size dict (shortest_edge/longest_edge)
|
| 135 |
size = {"shortest_edge": video_min_pixels, "longest_edge": video_max_pixels}
|
| 136 |
|
| 137 |
super().__init__(
|
|
|
|
| 163 |
|
| 164 |
def _preprocess_continuous_video(
|
| 165 |
self,
|
| 166 |
+
videos: List[torch.Tensor],
|
| 167 |
do_resize: bool,
|
| 168 |
size: SizeDict,
|
| 169 |
+
interpolation: F.InterpolationMode,
|
| 170 |
do_rescale: bool,
|
| 171 |
rescale_factor: float,
|
| 172 |
do_normalize: bool,
|
|
|
|
| 175 |
patch_size: int,
|
| 176 |
temporal_patch_size: int,
|
| 177 |
merge_size: int,
|
| 178 |
+
) -> dict:
|
| 179 |
+
"""Preprocess a single video for continuous vision features.
|
| 180 |
|
| 181 |
+
Performs group_videos_by_shape -> resize (torchvision) -> rescale_and_normalize -> patchify.
|
|
|
|
| 182 |
|
| 183 |
Args:
|
| 184 |
+
videos: List of channel-first torch tensors, each of shape (num_frames, C, H, W).
|
| 185 |
+
do_resize: Whether to perform resizing.
|
| 186 |
+
size: SizeDict with shortest_edge/longest_edge (smart_resize min/max pixels).
|
| 187 |
interpolation: torchvision InterpolationMode.
|
| 188 |
+
do_rescale: Whether to perform rescaling.
|
| 189 |
+
rescale_factor: Rescale factor.
|
| 190 |
+
do_normalize: Whether to perform normalization.
|
| 191 |
+
image_mean: Normalization mean (tuple).
|
| 192 |
+
image_std: Normalization standard deviation (tuple).
|
| 193 |
+
patch_size: ViT patch size.
|
| 194 |
+
temporal_patch_size: Temporal patch size.
|
| 195 |
+
merge_size: Token merge size.
|
| 196 |
|
| 197 |
Returns:
|
| 198 |
+
Dictionary with:
|
| 199 |
+
- "pixel_values_videos": Tensor of shape (grid_t * grid_h * grid_w, feat_dim).
|
| 200 |
+
- "video_grid_thw": List of [grid_t, grid_h, grid_w].
|
| 201 |
+
- "num_video_tokens": Number of continuous tokens (int).
|
| 202 |
"""
|
|
|
|
| 203 |
grouped_videos, grouped_videos_index = group_videos_by_shape(videos)
|
| 204 |
|
| 205 |
resized_videos_grouped = {}
|
|
|
|
| 270 |
"num_video_tokens": num_video_tokens,
|
| 271 |
}
|
| 272 |
|
| 273 |
+
def _preprocess_discrete_video(self, video: torch.Tensor) -> dict:
|
| 274 |
+
"""Preprocess a single video for discrete vision tokens (not yet implemented).
|
| 275 |
+
|
| 276 |
+
Args:
|
| 277 |
+
video: Video tensor.
|
| 278 |
+
|
| 279 |
+
Returns:
|
| 280 |
+
Empty dictionary.
|
| 281 |
+
"""
|
| 282 |
return {}
|
| 283 |
|
| 284 |
def preprocess(
|
|
|
|
| 287 |
return_tensors: Optional[Union[str, TensorType]] = None,
|
| 288 |
**kwargs,
|
| 289 |
) -> BatchFeature:
|
| 290 |
+
"""Preprocess a batch of videos.
|
| 291 |
|
| 292 |
+
Follows the same flow as BaseVideoProcessor.preprocess():
|
| 293 |
+
1. numpy (NHWC) -> channel-first torch (NCHW) conversion
|
| 294 |
+
2. kwargs resolution and resample -> interpolation, mean/std -> tuple conversion
|
| 295 |
+
3. _preprocess_continuous_video call per video
|
| 296 |
|
| 297 |
Args:
|
| 298 |
+
videos: Video input. Either:
|
| 299 |
+
- np.ndarray: Single video of shape (num_frames, H, W, C).
|
| 300 |
+
- List[np.ndarray]: Batch of videos, each 4D.
|
| 301 |
+
return_tensors: Desired tensor type for outputs.
|
| 302 |
|
| 303 |
Returns:
|
| 304 |
BatchFeature with:
|
| 305 |
+
- pixel_values_videos: Tensor of shape (total_patches, feat_dim).
|
| 306 |
+
- video_grid_thw: Tensor of shape (num_videos, 3).
|
| 307 |
+
- num_video_tokens: Tensor of shape (num_videos,).
|
| 308 |
"""
|
| 309 |
if isinstance(videos, np.ndarray) and videos.ndim == 4:
|
| 310 |
videos = [videos]
|
| 311 |
|
| 312 |
+
# 1. Resolve kwargs from self attributes
|
| 313 |
do_resize = kwargs.pop("do_resize", kwargs.pop("video_do_resize", None))
|
| 314 |
if do_resize is None:
|
| 315 |
do_resize = self.do_resize
|
|
|
|
| 354 |
if merge_size is None:
|
| 355 |
merge_size = self.video_merge_size
|
| 356 |
|
| 357 |
+
# Size dict (shortest_edge/longest_edge)
|
| 358 |
min_pixels = kwargs.pop("min_pixels", kwargs.pop("video_min_pixels", None))
|
| 359 |
if min_pixels is None:
|
| 360 |
min_pixels = self.size["shortest_edge"]
|
|
|
|
| 365 |
|
| 366 |
size = SizeDict(shortest_edge=min_pixels, longest_edge=max_pixels)
|
| 367 |
|
| 368 |
+
# 2. Convert resample -> interpolation, mean/std -> tuple
|
|
|
|
| 369 |
if isinstance(resample, (PILImageResampling, int)):
|
| 370 |
interpolation = pil_torch_interpolation_mapping[resample]
|
| 371 |
else:
|
|
|
|
| 376 |
if isinstance(image_std, list):
|
| 377 |
image_std = tuple(image_std)
|
| 378 |
|
| 379 |
+
# 3. Per-video processing
|
| 380 |
pixel_values_list = []
|
| 381 |
grid_thw_list = []
|
| 382 |
num_video_tokens_list = []
|
| 383 |
|
| 384 |
for video in videos:
|
| 385 |
+
# numpy (NHWC) -> channel-first torch (NCHW)
|
| 386 |
if isinstance(video, np.ndarray):
|
| 387 |
video = to_channel_dimension_format(video, ChannelDimension.FIRST)
|
| 388 |
video = torch.from_numpy(video).contiguous()
|
| 389 |
|
|
|
|
| 390 |
if do_convert_rgb:
|
| 391 |
video = self.convert_to_rgb(video)
|
| 392 |
|
|
|
|
| 421 |
image_width: Optional[int] = None,
|
| 422 |
image_height: Optional[int] = None,
|
| 423 |
num_frames: Optional[int] = None,
|
| 424 |
+
pixel_values_videos: Optional[torch.Tensor] = None,
|
| 425 |
include_boundary_tokens: bool = False,
|
| 426 |
patch_size: Optional[int] = None,
|
| 427 |
temporal_patch_size: Optional[int] = None,
|
| 428 |
merge_size: Optional[int] = None,
|
| 429 |
min_pixels: Optional[int] = None,
|
| 430 |
max_pixels: Optional[int] = None,
|
| 431 |
+
return_tuple: Optional[bool] = None,
|
| 432 |
+
) -> int:
|
| 433 |
+
"""Compute the number of video tokens for the given input.
|
| 434 |
+
|
| 435 |
+
Args:
|
| 436 |
+
image_width: Frame width (used when pixel_values_videos is None).
|
| 437 |
+
image_height: Frame height (used when pixel_values_videos is None).
|
| 438 |
+
num_frames: Number of frames (used when pixel_values_videos is None).
|
| 439 |
+
pixel_values_videos: Pre-computed pixel values tensor.
|
| 440 |
+
include_boundary_tokens: Whether to include start/end boundary tokens.
|
| 441 |
+
patch_size: ViT patch size. Defaults to self.video_patch_size.
|
| 442 |
+
temporal_patch_size: Temporal patch size. Defaults to self.video_temporal_patch_size.
|
| 443 |
+
merge_size: Token reduction merge size. Defaults to self.video_merge_size.
|
| 444 |
+
min_pixels: Minimum pixel count. Defaults to self.size["shortest_edge"].
|
| 445 |
+
max_pixels: Maximum pixel count. Defaults to self.size["longest_edge"].
|
| 446 |
+
return_tuple: If True, return (continuous, discrete) tuple.
|
| 447 |
+
Otherwise return the sum.
|
| 448 |
+
|
| 449 |
+
Returns:
|
| 450 |
+
Token count as int, or (continuous, discrete) tuple if return_tuple is True.
|
| 451 |
+
"""
|
| 452 |
patch_size = patch_size if patch_size is not None else self.video_patch_size
|
| 453 |
temporal_patch_size = temporal_patch_size if temporal_patch_size is not None else self.video_temporal_patch_size
|
| 454 |
merge_size = merge_size if merge_size is not None else self.video_merge_size
|
|
|
|
| 474 |
if include_boundary_tokens:
|
| 475 |
num_continuous_tokens += 2
|
| 476 |
|
| 477 |
+
if return_tuple:
|
| 478 |
+
return (num_continuous_tokens, num_discrete_tokens)
|
| 479 |
+
else:
|
| 480 |
+
return num_continuous_tokens + num_discrete_tokens
|