CCCCyx commited on
Commit
80bb676
·
verified ·
1 Parent(s): 60edb88

Add files using upload-large-folder tool

Browse files
.gitattributes CHANGED
@@ -34,3 +34,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  tokenizer.json filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  tokenizer.json filter=lfs diff=lfs merge=lfs -text
37
+ assets/benchmark-offline.png filter=lfs diff=lfs merge=lfs -text
38
+ assets/mossvl_quantization_benchmark_comparison_zh_4k.png filter=lfs diff=lfs merge=lfs -text
39
+ assets/mossvl_quantization_benchmark_comparison_en_4k.png filter=lfs diff=lfs merge=lfs -text
40
+ assets/architecture.png filter=lfs diff=lfs merge=lfs -text
41
+ assets/logo.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -8,61 +8,174 @@ pipeline_tag: video-text-to-text
8
  base_model: OpenMOSS-Team/MOSS-VL-Instruct-0708
9
  tags:
10
  - MOSS-VL
11
- - offline
12
- - quantized
13
- - nf4
14
  - bitsandbytes
 
 
15
  - custom_code
16
  ---
17
 
18
- # OpenMOSS-Team/MOSS-VL-Instruct-0708-NF4
 
 
 
 
 
 
 
 
19
 
20
- This is the Transformers offline release of MOSS-VL Instruct 0708 with
21
- bitsandbytes NF4 weights. It supports image and video inference through the
22
- standard MOSS-VL `offline_generate` path.
 
23
 
24
- ## Quantization
25
 
26
- | Component | Precision |
 
 
 
 
 
 
27
  | --- | --- |
28
- | 240 eligible Linear layers in language layers 4-43 | bitsandbytes NF4 weight-only with double quantization; BF16 compute |
29
  | First four and last four language layers | BF16 |
30
  | Cross-attention projection modules | BF16 |
31
  | Vision encoder and merger | BF16 |
32
  | Embeddings, norms and `lm_head` | BF16 |
33
- | Transformers KV cache | BF16 (`KV16`) |
 
34
 
35
- This checkpoint does **not** enable HQQ KV8: `generation_config.json` has no
36
- quantized-cache setting. The canonical name therefore ends in `KV16`.
 
37
 
38
- ## Validated Environment
39
 
40
- ```text
41
- Python: 3.12.8
42
- torch: 2.8.0+cu128
43
- transformers: 4.57.1
44
- bitsandbytes: 0.49.2
45
- accelerate: 1.12.0
46
- flash-attn: 2.8.1
47
- ```
 
 
 
 
 
48
 
49
- Use the existing environment without upgrading packages:
 
 
50
 
51
  ```bash
52
- source /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/activate
 
 
 
 
 
 
 
53
  ```
54
 
55
- ## Transformers Offline Validation
56
 
57
- The official runner is:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
- ```text
60
- /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  ```
62
 
63
- Direct image validation:
 
 
 
64
 
65
  ```bash
 
 
66
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
67
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
68
  --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
@@ -70,11 +183,7 @@ Direct image validation:
70
  --input /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/inputs/offline_image.json \
71
  --output /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/results/offline_nf4_image_output.json \
72
  --timeout-seconds 300
73
- ```
74
-
75
- Direct video validation:
76
 
77
- ```bash
78
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
79
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
80
  --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
@@ -84,12 +193,14 @@ Direct video validation:
84
  --timeout-seconds 300
85
  ```
86
 
87
- The latest validation passed both cases. Peak process memory was 12,494 MiB
88
- for the image and 16,708 MiB for the 1 FPS, maximum-32-frame video. The outputs
89
- correctly described the receipt and the Starbucks scene.
90
-
91
- Full inputs, memory-monitor commands and raw results:
92
 
93
  ```text
94
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811
95
  ```
 
 
 
 
 
 
 
8
  base_model: OpenMOSS-Team/MOSS-VL-Instruct-0708
9
  tags:
10
  - MOSS-VL
11
+ - image-understanding
12
+ - video-understanding
 
13
  - bitsandbytes
14
+ - NF4
15
+ - quantized
16
  - custom_code
17
  ---
18
 
19
+ <p align="center">
20
+ <img src="assets/logo.png" width="300" alt="MOSS-VL"/>
21
+ </p>
22
+
23
+ <p align="center">
24
+ English | <a href="https://huggingface.co/OpenMOSS-Team/MOSS-VL-Instruct-0708-NF4/blob/main/README_zh.md">中文</a>
25
+ </p>
26
+
27
+ # MOSS-VL-Instruct-0708 W4A16 NF4
28
 
29
+ This is the Transformers NF4 release of
30
+ [MOSS-VL-Instruct-0708](https://huggingface.co/OpenMOSS-Team/MOSS-VL-Instruct-0708).
31
+ It supports image and video inference through the standard MOSS-VL offline
32
+ inference path. This checkpoint is not an SGLang release.
33
 
34
+ ## Architecture
35
 
36
+ <p align="center">
37
+ <img src="assets/architecture.png" alt="MOSS-VL architecture" width="100%"/>
38
+ </p>
39
+
40
+ ## Quantization profile
41
+
42
+ | Component | Format |
43
  | --- | --- |
44
+ | 240 eligible Linear layers in language layers 4-43 | bitsandbytes NF4 weight-only quantization with double quantization and BF16 compute |
45
  | First four and last four language layers | BF16 |
46
  | Cross-attention projection modules | BF16 |
47
  | Vision encoder and merger | BF16 |
48
  | Embeddings, norms and `lm_head` | BF16 |
49
+ | Transformers KV cache | BF16 |
50
+ | Attention backend | FlashAttention 2 |
51
 
52
+ The checkpoint carries its bitsandbytes configuration. Load it directly and
53
+ do not add a second runtime quantization configuration. This variant does not
54
+ enable HQQ KV8; `generation_config.json` uses the standard BF16 KV cache.
55
 
56
+ ## Base model benchmark
57
 
58
+ The following figure reports the benchmark results of the original
59
+ MOSS-VL-Instruct-0708 release. It provides base-model context; it is not
60
+ presented as a separate quality evaluation of this NF4 checkpoint.
61
+
62
+ <p align="center">
63
+ <img src="assets/benchmark-offline.png" alt="MOSS-VL-Instruct-0708 benchmark" width="100%"/>
64
+ </p>
65
+
66
+ ## Hardware requirements
67
+
68
+ The validated image test peaked at 12,494 MiB of process VRAM. The 1 FPS,
69
+ maximum-32-frame video test peaked at 16,708 MiB. A single NVIDIA GPU with
70
+ 24 GB of VRAM is sufficient for the validated profile.
71
 
72
+ ## Environment
73
+
74
+ ### Installation
75
 
76
  ```bash
77
+ git clone https://github.com/OpenMOSS/MOSS-VL.git
78
+ cd MOSS-VL
79
+
80
+ conda create -n moss_vl_quant python=3.12 pip -y
81
+ conda activate moss_vl_quant
82
+ pip install -i https://pypi.org/simple --no-build-isolation -r requirements.txt
83
+ pip install -i https://pypi.org/simple bitsandbytes==0.49.2
84
+ python -m pip check
85
  ```
86
 
87
+ Validated core versions:
88
 
89
+ | Package | Version |
90
+ | --- | --- |
91
+ | Python | 3.12.8 |
92
+ | PyTorch | 2.8.0 + CUDA 12.8 |
93
+ | Transformers | 4.57.1 |
94
+ | Accelerate | 1.12.0 |
95
+ | FlashAttention | 2.8.1 |
96
+ | bitsandbytes | 0.49.2 |
97
+
98
+ Video decoding also requires FFmpeg in `PATH`.
99
+
100
+ ### Load the model
101
+
102
+ ```python
103
+ import torch
104
+ from transformers import AutoModelForCausalLM, AutoProcessor
105
+
106
+ checkpoint = "OpenMOSS-Team/MOSS-VL-Instruct-0708-NF4"
107
+
108
+ processor = AutoProcessor.from_pretrained(
109
+ checkpoint,
110
+ trust_remote_code=True,
111
+ frame_extract_num_threads=1,
112
+ )
113
+ model = AutoModelForCausalLM.from_pretrained(
114
+ checkpoint,
115
+ trust_remote_code=True,
116
+ device_map="auto",
117
+ torch_dtype=torch.bfloat16,
118
+ attn_implementation="flash_attention_2",
119
+ )
120
+ model.eval()
121
+ ```
122
 
123
+ ## Image inference
124
+
125
+ ```python
126
+ text = model.offline_image_generate(
127
+ processor,
128
+ prompt="Describe this image.",
129
+ image="data/example_image.jpg",
130
+ shortest_edge=4096,
131
+ longest_edge=16777216,
132
+ multi_image_max_pixels=201326592,
133
+ patch_size=16,
134
+ temporal_patch_size=1,
135
+ merge_size=2,
136
+ image_mean=[0.5, 0.5, 0.5],
137
+ image_std=[0.5, 0.5, 0.5],
138
+ max_new_tokens=256,
139
+ do_sample=False,
140
+ vision_chunked_length=64,
141
+ )
142
+ print(text)
143
+ ```
144
+
145
+ ## Video inference
146
+
147
+ ```python
148
+ text = model.offline_video_generate(
149
+ processor,
150
+ prompt="Describe this video.",
151
+ video="data/example_video.mp4",
152
+ shortest_edge=4096,
153
+ longest_edge=16777216,
154
+ video_max_pixels=201326592,
155
+ patch_size=16,
156
+ temporal_patch_size=1,
157
+ merge_size=2,
158
+ video_fps=1.0,
159
+ min_frames=1,
160
+ max_frames=32,
161
+ num_extract_threads=4,
162
+ image_mean=[0.5, 0.5, 0.5],
163
+ image_std=[0.5, 0.5, 0.5],
164
+ max_new_tokens=256,
165
+ do_sample=False,
166
+ vision_chunked_length=64,
167
+ )
168
+ print(text)
169
  ```
170
 
171
+ ## Validated reproduction
172
+
173
+ The official runner passed both the receipt image and the 1 FPS Starbucks
174
+ video tests:
175
 
176
  ```bash
177
+ source /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/activate
178
+
179
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
180
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
181
  --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
 
183
  --input /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/inputs/offline_image.json \
184
  --output /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/results/offline_nf4_image_output.json \
185
  --timeout-seconds 300
 
 
 
186
 
 
187
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
188
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
189
  --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
 
193
  --timeout-seconds 300
194
  ```
195
 
196
+ Full inputs, commands and raw results:
 
 
 
 
197
 
198
  ```text
199
  /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811
200
  ```
201
+
202
+ ## Configuration files
203
+
204
+ - `config.json`: model and bitsandbytes NF4 configuration.
205
+ - `generation_config.json`: standard generation settings with BF16 KV cache.
206
+ - `modeling_moss_vl.py`: checkpoint-local offline MOSS-VL code.
README_zh.md ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ language:
4
+ - en
5
+ - zh
6
+ library_name: transformers
7
+ pipeline_tag: video-text-to-text
8
+ base_model: OpenMOSS-Team/MOSS-VL-Instruct-0708
9
+ tags:
10
+ - MOSS-VL
11
+ - image-understanding
12
+ - video-understanding
13
+ - bitsandbytes
14
+ - NF4
15
+ - quantized
16
+ - custom_code
17
+ ---
18
+
19
+ <p align="center">
20
+ <img src="assets/logo.png" width="300" alt="MOSS-VL"/>
21
+ </p>
22
+
23
+ <p align="center">
24
+ <a href="https://huggingface.co/OpenMOSS-Team/MOSS-VL-Instruct-0708-NF4/blob/main/README.md">English</a> | 中文
25
+ </p>
26
+
27
+ # MOSS-VL-Instruct-0708 W4A16 NF4
28
+
29
+ 这是 [MOSS-VL-Instruct-0708](https://huggingface.co/OpenMOSS-Team/MOSS-VL-Instruct-0708)
30
+ 的 Transformers NF4 发布版本,支持 MOSS-VL 标准离线图片和视频推理。
31
+ 该 checkpoint 不是 SGLang 发布版本。
32
+
33
+ ## 模型架构
34
+
35
+ <p align="center">
36
+ <img src="assets/architecture.png" alt="MOSS-VL 模型架构" width="100%"/>
37
+ </p>
38
+
39
+ ## 量化方法
40
+
41
+ | 模块 | 格式 |
42
+ | --- | --- |
43
+ | 第 4-43 层中的 240 个可量化 Linear | bitsandbytes NF4 weight-only,启用 double quantization,BF16 计算 |
44
+ | 前四层和后四层语言模型层 | BF16 |
45
+ | Cross-attention projection | BF16 |
46
+ | 视觉编码器和 merger | BF16 |
47
+ | Embedding、norm 和 `lm_head` | BF16 |
48
+ | Transformers KV Cache | BF16 |
49
+ | Attention 后端 | FlashAttention 2 |
50
+
51
+ checkpoint 已包含 bitsandbytes 配置,加载时不要再传入第二份运行时量化配置。
52
+ 该版本没有启用 HQQ KV8,`generation_config.json` 使用标准 BF16 KV Cache。
53
+
54
+ ## 基础模型 Benchmark
55
+
56
+ 下图是原始 MOSS-VL-Instruct-0708 的 benchmark,用于说明基础模型能力;
57
+ 它不作为该 NF4 checkpoint 的独立精度测评结果。
58
+
59
+ <p align="center">
60
+ <img src="assets/benchmark-offline.png" alt="MOSS-VL-Instruct-0708 benchmark" width="100%"/>
61
+ </p>
62
+
63
+ ## 硬件要求
64
+
65
+ 图片实测进程峰值显存为 12,494 MiB;1 FPS、最多 32 帧的视频实测峰值为
66
+ 16,708 MiB。单张 24 GB 显存的 NVIDIA GPU 可以运行已验证配置。
67
+
68
+ ## 环境安装
69
+
70
+ ```bash
71
+ git clone https://github.com/OpenMOSS/MOSS-VL.git
72
+ cd MOSS-VL
73
+
74
+ conda create -n moss_vl_quant python=3.12 pip -y
75
+ conda activate moss_vl_quant
76
+ pip install -i https://pypi.org/simple --no-build-isolation -r requirements.txt
77
+ pip install -i https://pypi.org/simple bitsandbytes==0.49.2
78
+ python -m pip check
79
+ ```
80
+
81
+ 已验证的主要环境版本:
82
+
83
+ | 依赖 | 版本 |
84
+ | --- | --- |
85
+ | Python | 3.12.8 |
86
+ | PyTorch | 2.8.0 + CUDA 12.8 |
87
+ | Transformers | 4.57.1 |
88
+ | Accelerate | 1.12.0 |
89
+ | FlashAttention | 2.8.1 |
90
+ | bitsandbytes | 0.49.2 |
91
+
92
+ 视频解码还需要确保 FFmpeg 已加入 `PATH`。
93
+
94
+ ## 加载模型
95
+
96
+ ```python
97
+ import torch
98
+ from transformers import AutoModelForCausalLM, AutoProcessor
99
+
100
+ checkpoint = "OpenMOSS-Team/MOSS-VL-Instruct-0708-NF4"
101
+
102
+ processor = AutoProcessor.from_pretrained(
103
+ checkpoint,
104
+ trust_remote_code=True,
105
+ frame_extract_num_threads=1,
106
+ )
107
+ model = AutoModelForCausalLM.from_pretrained(
108
+ checkpoint,
109
+ trust_remote_code=True,
110
+ device_map="auto",
111
+ torch_dtype=torch.bfloat16,
112
+ attn_implementation="flash_attention_2",
113
+ )
114
+ model.eval()
115
+ ```
116
+
117
+ ## 图片推理
118
+
119
+ ```python
120
+ text = model.offline_image_generate(
121
+ processor,
122
+ prompt="请描述这张图片。",
123
+ image="data/example_image.jpg",
124
+ max_new_tokens=256,
125
+ do_sample=False,
126
+ vision_chunked_length=64,
127
+ )
128
+ print(text)
129
+ ```
130
+
131
+ ## 视频推理
132
+
133
+ ```python
134
+ text = model.offline_video_generate(
135
+ processor,
136
+ prompt="请描述这段视频。",
137
+ video="data/example_video.mp4",
138
+ video_fps=1.0,
139
+ min_frames=1,
140
+ max_frames=32,
141
+ max_new_tokens=256,
142
+ do_sample=False,
143
+ vision_chunked_length=64,
144
+ )
145
+ print(text)
146
+ ```
147
+
148
+ ## 完整复测命令
149
+
150
+ 官方 runner 已通过收据图片和 1 FPS 星巴克视频测试:
151
+
152
+ ```bash
153
+ source /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/activate
154
+
155
+ /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
156
+ /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
157
+ --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
158
+ --mode image \
159
+ --input /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/inputs/offline_image.json \
160
+ --output /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/results/offline_nf4_image_output.json \
161
+ --timeout-seconds 300
162
+
163
+ /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/venv/bin/python \
164
+ /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/mossvl-github/MOSS-VL/inference/run_inference.py \
165
+ --checkpoint /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/final_release/quant/MOSS-VL-0708-Offline-NF4-Keep4-KV16 \
166
+ --mode video \
167
+ --input /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/inputs/offline_video.json \
168
+ --output /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811/results/offline_nf4_video_output.json \
169
+ --timeout-seconds 300
170
+ ```
171
+
172
+ 完整输入、命令和原始结果:
173
+
174
+ ```text
175
+ /inspire/qb-ilm/project/video-understanding/public/train/moss_vl_streaming/8B/quant/transformers_validation_20260811
176
+ ```
assets/architecture.png ADDED

Git LFS Details

  • SHA256: 28e51b34e031c884c540601d6b6651576c65836dc252694a1dc7dc0b1fc15237
  • Pointer size: 132 Bytes
  • Size of remote file: 6.09 MB
assets/benchmark-offline.png ADDED

Git LFS Details

  • SHA256: 82819674c2c8c62be9d6a25f324a7e9143f045cf4bc23acb813b9910aa2e9819
  • Pointer size: 132 Bytes
  • Size of remote file: 1.51 MB
assets/logo.png ADDED

Git LFS Details

  • SHA256: 37bf0241f5fbab73fc955827f477befc95b88b0d3618c31628099b70ea1dd232
  • Pointer size: 131 Bytes
  • Size of remote file: 941 kB
assets/mossvl_quantization_benchmark_comparison_en_4k.png ADDED

Git LFS Details

  • SHA256: 75ed545c603986ffe7e8ce419f3bc49796a427c5f288a919b7d2bd805f44e5e4
  • Pointer size: 132 Bytes
  • Size of remote file: 2.8 MB
assets/mossvl_quantization_benchmark_comparison_zh_4k.png ADDED

Git LFS Details

  • SHA256: 8fda6adf7c96f7ce07e4dfc354882b321c1ff9ccf729b5584f816d10cf209631
  • Pointer size: 132 Bytes
  • Size of remote file: 2.68 MB