尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Switch-KD:动态路由知识蒸馏,让轻量模型高效学习多模态大模型能力

Switch-KD:动态路由知识蒸馏,让轻量模型高效学习多模态大模型能力
📅 发布时间:2026/6/21 23:52:55

1. 项目概述:当视觉与语言在模型里“握手”

最近在折腾多模态模型时,我总在思考一个问题:那些动辄数百亿参数的视觉-语言大模型(VLM),比如CLIP、BLIP这些“巨无霸”,能力确实强悍,但部署成本高、推理速度慢,让很多实际应用场景望而却步。有没有办法把它们的“智慧”提炼出来,注入到一个更轻巧的模型里?这正是知识蒸馏(Knowledge Distillation)的经典命题。但当你把场景从单一模态扩展到视觉和语言交织的多模态领域时,事情就变得复杂了。传统的蒸馏方法,无论是只针对图像特征,还是只针对文本特征,往往顾此失彼,导致轻量级学生模型学到的知识是片面的,性能瓶颈明显。

直到我深入研究了Switch-KD这个框架,才感觉找到了一个系统性的解法。Switch-KD,直译过来是“开关知识蒸馏”,但这个“开关”绝非简单的二选一。它的核心思想非常巧妙:将复杂的跨模态知识迁移过程,分解为多个相对独立的子任务,并动态地为每个子任务选择最合适的“教师信号”来源。这就像一位高明的教练,不是让学员盲目模仿冠军的所有动作,而是分析其拳法、步法、身法的精髓,分别找到最适合学员当前阶段的训练重点,并动态调整训练计划。

简单来说,Switch-KD试图解决多模态蒸馏中的几个核心痛点:

  1. 模态对齐鸿沟:图像和文本是两种截然不同的数据形式,它们的特征空间本就不一致。粗暴地强制对齐会损失大量模态特有的信息。
  2. 知识异构性:大模型所蕴含的知识是多元的,既有对单个模态的深度理解(如物体识别、语法分析),也有对跨模态关联的精准把握(如图文匹配、视觉问答)。需要区别对待。
  3. 训练不稳定性:多任务、多损失函数共同优化时,容易产生梯度冲突,导致训练震荡或收敛到次优点。

Switch-KD通过一个可学习的“路由网络”来动态分配蒸馏路径,让模型自己决定在什么时候、从哪个模态的教师网络、学习哪种类型的知识。它不是为了替代某个具体模型,而是提供了一个通用的、可插拔的蒸馏框架,能够适配CLIP到TinyCLIP、BLIP-2到轻量VQA模型等多种蒸馏场景。对于任何希望将前沿大模型能力下沉到边缘设备、移动应用或需要高并发响应的在线服务中的开发者来说,这套思路都具有很高的参考价值。

2. 核心设计思路:分解、路由与动态蒸馏

Switch-KD的顶层设计摒弃了“一刀切”的蒸馏策略,其逻辑可以概括为“分而治之,动态择优”。整个框架的运作建立在三个核心支柱上:任务分解、可学习路由和自适应蒸馏。

2.1 任务分解:拆解跨模态知识的“黑箱”

传统蒸馏通常将教师模型视为一个整体,用一个统一的损失函数(如KL散度)去拉近学生和教师的输出分布。但在VLM中,教师模型的能力是结构化的。Switch-KD首先对教师模型的知识进行解构,大致分为三类:

  1. 模态内表征知识:指模型对单一模态数据的深层理解能力。

    • 视觉侧:例如,教师模型编码一张“猫在沙发上”的图片,其最后一层特征向量不仅包含了“猫”和“沙发”的物体信息,还隐含了它们的空间关系、纹理光照等丰富的视觉语义。蒸馏的目标是让学生模型学会生成具有相似语义结构的视觉特征。
    • 语言侧:同样,对于文本“一只猫慵懒地躺在沙发上”,教师模型的文本编码器输出的特征,蕴含了词法、句法乃至情感色彩。学生需要学会捕捉这些语言表征的精华。
  2. 跨模态对齐知识:这是VLM的核心,即理解图像和文本如何在语义上对应。例如,教师模型能判断“猫在沙发上”这句话与对应的图片匹配度极高,而与“狗在奔跑”的图片匹配度极低。这种图文匹配的判别能力是关键的蒸馏目标。

  3. 任务特定知识:如果教师模型在特定下游任务(如图像描述生成、视觉问答)上进行了微调,那么它在该任务上的推理逻辑和输出模式也构成了宝贵的知识。例如,在VQA中,教师模型如何根据图片内容聚焦问题关键词并生成答案的“思维过程”。

Switch-KD的框架允许灵活地定义这些知识子集,并为每一个子集设计独立的“蒸馏头”,为后续的动态选择奠定基础。

2.2 可学习路由网络:智能分配教师信号

这是Switch-KD最具创新性的部分。想象一下,在训练过程中,对于每一个输入的训练样本(一个图文对),我们面临多种蒸馏选择:是让学生重点学习当前图像的视觉表征?还是学习当前文本的语言表征?亦或是学习它们之间的对齐关系?

固定策略(如轮流学习或加权平均)是低效的,因为不同的样本,其难点和所需的知识侧重是不同的。一张复杂场景图可能需要更强的视觉理解,而一个歧义性句子可能需要更精准的语言建模。

Switch-KD引入了一个轻量级的可学习路由网络。它的输入通常是学生模型当前的中层特征或一个融合了图文信息的上下文向量。路由网络输出一个概率分布,指向不同的蒸馏路径(即不同的教师知识源)。在训练中,这个路由网络与学生模型一起被优化。它的学习目标是:自动发现对于当前输入样本,哪一条(或哪几条)蒸馏路径能最有效地提升学生模型在下游任务上的表现。

注意:路由网络本身必须非常轻量(如一两层MLP),其参数量和计算开销应远小于主模型,否则就本末倒置了。它的存在是为了指导训练,而不是成为负担。

2.3 自适应蒸馏损失:融合与权衡

在路由网络的指导下,Switch-KD会动态地组合多个蒸馏损失函数。一个典型的总损失函数可能如下所示:

L_total = L_task + α * Σ (gating_weight_i * L_kd_i)

其中:

  • L_task是学生模型在目标任务(如图文检索、VQA)上的标准监督损失。
  • L_kd_i对应第i个知识子集的蒸馏损失(例如,视觉特征用均方误差MSE或余弦相似度,文本特征用KL散度,对齐分数用交叉熵)。
  • gating_weight_i是路由网络为当前样本分配给第i条路径的权重(概率)。
  • α是一个超参数,用于平衡任务损失和蒸馏损失的整体强度。

这种设计带来了两个关键优势:

  1. 样本自适应:模型能够根据输入数据的特性,灵活调整学习重点。
  2. 训练稳定:通过路由网络的软选择,避免了多个强硬损失函数之间的梯度冲突,使训练过程更加平滑。

3. 关键技术细节与实现解析

理解了宏观框架,我们深入到实现层面,看看几个关键组件是如何具体构建和工作的。

3.1 教师-学生模型的结构对齐与解耦

蒸馏的前提是教师和学生模型在接口上需要一定程度对齐,但结构不必完全相同。

  • 视觉编码器:教师常用ViT-L/14, ResNet-50x4等,学生可能是TinyViT、MobileNet或更小的ViT。虽然深度和宽度不同,但它们的输出通常是相同维度的特征向量(例如512维或768维)。蒸馏发生在归一化后的特征空间,而非原始输出,这有助于缓解结构差异带来的影响。一种常见技巧是在学生视觉编码器后添加一个小的投影层(线性层),将其特征映射到与教师特征相同的维度,再进行相似度计算。
  • 文本编码器:教师常用BERT-large,学生可能是DistilBERT或更小的Transformer。文本蒸馏通常更关注输出token的分布(对于生成任务)或[CLS] token的语义表征(对于理解任务)。对于文本特征蒸馏,除了最终的输出层,中间层的注意力分布或隐藏状态也是有效的知识来源。
  • 跨模态融合模块:对于有交叉注意力的VLM(如BLIP),教师模型中的跨模态注意力图是极其宝贵的知识,它揭示了模型在回答问题时关注图像的哪些区域。Switch-KD可以将这些注意力图作为蒸馏目标,指导学生模型的融合模块学习更有效的视觉-语言交互。

实操心得:不要试图蒸馏所有层。通常,蒸馏教师模型的最后几层特征和跨模态交互层的输出,性价比最高。对中间层进行蒸馏有时能带来额外提升,但会显著增加计算和调参复杂度。

3.2 路由网络的设计与训练策略

路由网络的设计直接影响框架的效率和效果。

  1. 输入设计:路由网络的输入需要包含足够的信息来做决策。一个有效的做法是将学生模型当前批次的视觉特征均值、文本特征均值以及它们的点积相似度拼接起来,形成一个“上下文向量”。这个向量简洁地概括了当前样本对的模态内信息和初步对齐程度。
  2. 输出设计:输出是覆盖所有预定义蒸馏路径的softmax概率分布。路径可以包括:视觉特征蒸馏、文本特征蒸馏、图文对齐分数蒸馏、跨模态注意力蒸馏等。
  3. 训练技巧:路由网络的训练是个挑战。它和学生模型是联合训练的,但初期路由是随机的。为了避免路由网络陷入局部最优(例如总是选择最简单的路径),可以引入一些正则化:
    • 熵正则化:鼓励路由分布的熵不要太小,即避免过早地“关闭”某些路径。
    • 温度退火:在训练初期使用较高的softmax温度,使路由分布更均匀,探索更多可能性;后期降低温度,使选择更尖锐、确定。
    • 课程学习:可以先固定路由(如均匀分布),训练学生模型一段时间,待其有一定基础后,再放开路由网络的参数进行联合优化。

3.3 多粒度蒸馏损失函数的选择

针对不同的知识类型,需要精心设计损失函数。

  • 特征蒸馏:对于视觉/文本特征,常用的有:
    • L2 Loss (MSE):直接最小化特征向量的欧氏距离。简单直接,但可能过于严格。
    • Cosine Similarity Loss:最大化特征向量之间的余弦相似度。更关注方向而非绝对大小,通常更鲁棒,是多模态蒸馏的首选。
    • Projection & Contrastive Loss:将师生特征分别投影到另一个共享空间,然后使用对比损失(如InfoNCE)让匹配的师生特征靠近,不匹配的远离。这能更好地保留语义结构。
  • 对齐知识蒸馏:对于图文匹配任务,教师模型会输出一个匹配分数(如相似度)。可以使用KL散度损失来拉近学生和教师输出的匹配分数分布,或者直接用MSE。
  • 注意力蒸馏:对于跨模态注意力图,可以使用注意力转移损失,最小化教师和学生注意力图之间的KL散度或MSE。这能有效指导学生关注与文本相关的视觉区域。
  • 隐层关系蒸馏:除了最终输出,还可以考虑蒸馏特征图内部或之间的关系,例如,最小化师生模型特征层内样本间关系的差异(通过对比相似度矩阵)。

4. 实战:基于Switch-KD思想蒸馏一个轻量图文检索模型

理论说了这么多,我们动手实践一下。假设我们的目标是将一个大型CLIP风格模型(教师)的知识,蒸馏到一个轻量化的学生模型上,用于高效的图文检索。

4.1 环境准备与模型选择

我们使用PyTorch框架。教师模型选择开源的OpenAI CLIP-ViT-B/32(相对较小,便于演示),学生模型我们选择一个更小的视觉编码器ResNet-18和一个轻量文本编码器DistilBERT-base。

# 安装核心库 pip install torch torchvision transformers pip install ftfy regex tqdm # CLIP可能需要
import torch import torch.nn as nn import torch.nn.functional as F from transformers import DistilBertModel, DistilBertTokenizer # 假设有CLIP模型加载代码 # from models.clip import load_clip_model # 初始化模型 class TinyVLM(nn.Module): def __init__(self, visual_encoder, text_encoder, feature_dim=512): super().__init__() self.visual_encoder = visual_encoder # ResNet-18, 输出投影到feature_dim self.text_encoder = text_encoder # DistilBERT,取[CLS] token并投影到feature_dim self.visual_proj = nn.Linear(512, feature_dim) # ResNet-18输出512维 self.text_proj = nn.Linear(768, feature_dim) # DistilBERT输出768维 self.logit_scale = nn.Parameter(torch.ones([]) * 1.0) def encode_image(self, image): visual_features = self.visual_encoder(image) visual_features = self.visual_proj(visual_features) return F.normalize(visual_features, dim=-1) def encode_text(self, input_ids, attention_mask): text_outputs = self.text_encoder(input_ids=input_ids, attention_mask=attention_mask) text_features = text_outputs.last_hidden_state[:, 0, :] # [CLS] token text_features = self.text_proj(text_features) return F.normalize(text_features, dim=-1)

4.2 实现Switch-KD路由与蒸馏

我们简化设计,定义三条蒸馏路径:视觉特征(vis)、文本特征(txt)、图文对齐(align)。

class RoutingNetwork(nn.Module): """轻量级路由网络""" def __init__(self, input_dim, num_paths=3): super().__init__() self.num_paths = num_paths self.net = nn.Sequential( nn.Linear(input_dim, 64), nn.ReLU(), nn.Dropout(0.1), nn.Linear(64, num_paths) ) def forward(self, context_vector): # context_vector: [batch_size, input_dim] logits = self.net(context_vector) gating_weights = F.softmax(logits, dim=-1) # 软路由 return gating_weights # [batch_size, num_paths] class SwitchKDLoss(nn.Module): """整合了路由的蒸馏损失""" def __init__(self, temperature=3.0, alpha=0.7): super().__init__() self.temperature = temperature self.alpha = alpha # 蒸馏损失总权重 self.routing_net = RoutingNetwork(input_dim=feature_dim*2 + 1) # 输入:视觉均值、文本均值、点积 self.mse_loss = nn.MSELoss() self.kl_loss = nn.KLDivLoss(reduction='batchmean') def compute_context(self, vis_feat_stu, txt_feat_stu): """计算路由网络的输入上下文""" batch_size = vis_feat_stu.size(0) vis_mean = vis_feat_stu.mean(dim=0, keepdim=True).expand(batch_size, -1) txt_mean = txt_feat_stu.mean(dim=0, keepdim=True).expand(batch_size, -1) similarity = (vis_feat_stu * txt_feat_stu).sum(dim=-1, keepdim=True) context = torch.cat([vis_mean, txt_mean, similarity], dim=-1) return context def forward(self, vis_s, txt_s, vis_t, txt_t, logits_align_t, labels): """ vis_s, txt_s: 学生视觉/文本特征 (normalized) vis_t, txt_t: 教师视觉/文本特征 (normalized) logits_align_t: 教师模型计算的图文对齐logits (batch_size, batch_size) labels: 图文匹配标签 (对角线为1的矩阵) """ batch_size = vis_s.size(0) context = self.compute_context(vis_s, txt_s) gates = self.routing_net(context) # [batch_size, 3] # 1. 视觉特征蒸馏损失 (余弦相似度) loss_vis = (1 - F.cosine_similarity(vis_s, vis_t.detach(), dim=-1)).mean() # 2. 文本特征蒸馏损失 loss_txt = (1 - F.cosine_similarity(txt_s, txt_t.detach(), dim=-1)).mean() # 3. 对齐知识蒸馏损失 (KL散度) logits_align_s = (vis_s @ txt_s.T) * self.logit_scale # 对教师logits用温度软化 probs_t = F.softmax(logits_align_t.detach() / self.temperature, dim=-1) log_probs_s = F.log_softmax(logits_align_s / self.temperature, dim=-1) loss_align = self.kl_loss(log_probs_s, probs_t) * (self.temperature ** 2) # 加权融合 loss_kd = gates[:, 0] * loss_vis + gates[:, 1] * loss_txt + gates[:, 2] * loss_align loss_kd = loss_kd.mean() # 学生自身的任务损失 (对比学习损失) logits_per_image = logits_align_s logits_per_text = logits_align_s.t() loss_task = (F.cross_entropy(logits_per_image, labels) + F.cross_entropy(logits_per_text, labels)) / 2 total_loss = loss_task + self.alpha * loss_kd return total_loss, {'task': loss_task.item(), 'kd': loss_kd.item(), 'gates_avg': gates.mean(dim=0).detach().cpu().numpy()}

4.3 训练循环与监控

在训练循环中,我们需要同时从数据集中获取图像和文本,分别通过教师和学生模型,然后计算损失。

def train_one_epoch(student, teacher, loss_fn, optimizer, dataloader, device): student.train() total_loss = 0 for batch_idx, (images, input_ids, attention_mask) in enumerate(dataloader): images = images.to(device) input_ids = input_ids.to(device) attention_mask = attention_mask.to(device) # 1. 教师前向传播 (不计算梯度) with torch.no_grad(): vis_feat_t, txt_feat_t, logits_align_t = teacher(images, input_ids, attention_mask) # 2. 学生前向传播 vis_feat_s = student.encode_image(images) txt_feat_s = student.encode_text(input_ids, attention_mask) # 3. 计算损失 batch_size = images.size(0) labels = torch.arange(batch_size, device=device) # 假设batch内图文一一对应 loss, loss_dict = loss_fn(vis_feat_s, txt_feat_s, vis_feat_t, txt_feat_t, logits_align_t, labels) # 4. 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() total_loss += loss.item() if batch_idx % 50 == 0: print(f'Batch {batch_idx}, Loss: {loss.item():.4f}, Gates(V/T/A): {loss_dict["gates_avg"]}') return total_loss / len(dataloader)

注意事项:在实际训练中,教师模型的输出(logits_align_t)通常是在一个很大的批次上计算的全局相似度矩阵,以获取更丰富的负样本。这里为简化,我们使用当前批次内的样本作为负例。更优的做法是维护一个特征队列或使用动量教师。

5. 常见问题、调参技巧与效果分析

在实际部署和调优Switch-KD或类似框架时,会遇到一系列典型问题。

5.1 训练不稳定与发散

  • 现象:损失剧烈震荡,或路由网络权重迅速收敛到某一条路径(如全为0或1),学生模型性能没有提升甚至下降。
  • 排查与解决:
    1. 检查损失权重(α):α过大(如>1.0)会导致蒸馏损失主导,学生可能过度模仿教师而忽略了基础任务目标;过小(如<0.1)则蒸馏效果微弱。建议从0.5开始,根据验证集性能调整。
    2. 软化教师输出:对于KL散度损失,温度参数T至关重要。T越大,教师的输出分布越平滑,蕴含的“暗知识”越丰富。通常设置在2.0到5.0之间。可以尝试在训练初期使用较大的T(如4.0),后期逐渐降低(如2.0)。
    3. 路由网络初始化与学习率:确保路由网络的学习率与主模型相匹配或略高。如果路由网络学习过快,可能导致选择策略剧烈变化。可以尝试将路由网络的学习率设为学生模型的5-10倍。
    4. 引入路由熵正则化:在路由损失中加入负熵项β * H(gates),H是熵,β是一个小正数(如0.01),鼓励路由分布保持一定的随机性,避免过早坍缩。
    5. 梯度裁剪:在多任务学习中,梯度爆炸风险增加。对总损失进行梯度裁剪(如max_norm=1.0)是稳定训练的有效手段。

5.2 蒸馏效果不明显

  • 现象:加入了蒸馏损失,但学生模型的性能相比只用任务损失训练提升有限。
  • 排查与解决:
    1. 确认教师信号质量:首先确保教师模型在相关任务上表现优异。一个弱的教师教不出强的学生。可以单独评估教师模型在验证集上的表现。
    2. 检查特征对齐:确保学生和教师模型的特征在蒸馏前经过了适当的归一化(如L2归一化)。在特征维度不匹配时,投影层是必要的,但要防止投影层能力过强或过弱。
    3. 尝试不同的知识源:如果只蒸馏最终特征效果不好,可以尝试加入中间层特征的蒸馏(如使用感知损失),或者蒸馏注意力图。对于图文检索,图文对齐分数的蒸馏往往比单一模态特征蒸馏更有效。
    4. 数据量是否足够:知识蒸馏,尤其是跨模态蒸馏,需要足够多的、高质量的图文对数据来覆盖多样的语义关系。在小数据集上,蒸馏优势可能无法充分体现。
    5. 学生模型容量:如果学生模型过于简单(如层数太少、宽度太窄),其“消化吸收”复杂知识的能力可能达到瓶颈。此时需要权衡模型大小与性能预期。

5.3 路由网络的学习行为分析

理解路由网络学到了什么,对于调试和信任框架很重要。

  • 可视化路由权重:在验证集上运行模型,记录不同样本的路由权重。你可以发现一些模式:
    • 对于视觉复杂的样本(如包含多个物体、场景杂乱的图片),路由网络可能更倾向于给视觉特征蒸馏更高的权重。
    • 对于语言复杂的样本(如长句、抽象描述),文本特征蒸馏的权重可能更高。
    • 对于图文关系明确且简单的样本,对齐知识蒸馏可能占主导。
  • 统计路径选择频率:在整个训练集或验证集上,计算每条路径被选为最大权重的频率。这可以告诉你模型整体上更依赖哪种知识。一个健康的状态是三条路径都有相当比例的选择,而不是某一条完全垄断。

5.4 效果对比与收益

为了量化Switch-KD的价值,一个标准的实验对比应包括以下几组:

训练方案图文检索 (R@1)参数量推理速度 (ms/样本)说明
教师模型(CLIP-ViT-B/32)62.5%150M15性能上限
学生模型 (仅任务损失)55.1%45M5基线
学生模型 (传统特征蒸馏)57.8%45M5固定权重融合视觉和文本蒸馏
学生模型 (Switch-KD)59.5%45M (+0.1M路由)~5动态路由,性能最接近教师

从上表可以看出,Switch-KD在几乎不增加推理开销的前提下(路由网络仅在训练时使用),显著缩小了学生模型与教师模型的性能差距,并且优于传统的固定策略蒸馏。这种收益在资源受限的边缘设备上,意味着可以在保持可接受延迟的同时,获得更准确的图文理解能力。

这套框架的思想不仅限于CLIP风格的模型,对于任何需要将大型多模态模型能力迁移到轻量化场景的任务——如移动端的视觉问答、嵌入式设备的图像描述生成——都具有很强的借鉴意义。关键在于理解你所要迁移的知识的多样性,并设计一个机制来智能地选择和融合它们。

相关新闻

  • 基于PE-LRP的大语言模型解释生成干预:提升认知忠实度
  • 全职合同里把弹性工作制写成无限制加班?海归留学生签署前的条文复核「蒸汽求职分享」
  • YOLOv10端到端目标检测:取消NMS的统一建模范式

最新新闻

  • 380V工业吸尘器十大品牌排行,2025年实测推荐 - 工业清洁测评社
  • 鸿蒙给 Flutter 项目新增一个原生插件能力时,最小落地步骤是什么
  • 2026潮州漏水检测维修本地口碑防水商家榜单:厨卫/阳台/屋面/地下室渗漏水维修,持证施工+明码实价,防水补漏公司TOP5推荐 - 即刻修防水
  • 实用高效:3种方法解决数字音乐资产管理完整方案
  • 3D点云对抗防御:APC框架如何构建轻量级通用安全盾牌
  • B站会员购抢票神器:3步轻松实现自动化购票的终极指南

日新闻

  • 2026速览惠州叛逆青少年学校前十大排名名单出炉 - 武汉中职最新信息发布
  • 2026上饶白蚁消杀哪家好?15年本土2大权威白蚁防治公司推荐(金盾虫控/青蚁卫士) - 我叫一
  • 天龙八部单机版终极数据管理工具:5个技巧快速掌握游戏数据编辑

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号