免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

MoE架构与多模态AI:解析Inkling-Small模型的高效部署与应用

MoE架构与多模态AI:解析Inkling-Small模型的高效部署与应用 最近AI社区里关于“大模型”的讨论似乎陷入了一个怪圈参数规模越来越大动辄千亿、万亿仿佛参数数量成了衡量模型能力的唯一标尺。但作为一线开发者和研究者我们心里都清楚这背后是天文数字般的训练成本和令人望而却步的部署门槛。一个模型再“聪明”如果无法在常规的GPU集群上高效运行那它对大多数团队来说就只是一个“学术玩具”。就在这个背景下Thinking Machines Lab 发布的Inkling-Small模型像是一股清流。它最引人注目的标签是总参数 276B但激活参数仅 12B。这意味着什么简单说它拥有一个“巨人的知识库”276B参数但每次推理时只调用其中一小部分“专家”12B参数。这种被称为MoEMixture of Experts混合专家的架构正是解决大模型“又大又笨重”痛点的关键技术路径之一。更重要的是Inkling-Small 是一个多模态模型能够理解和生成文本与图像并且其权重是开源的采用宽松的Apache 2.0 协议。这直接打破了“强大模型必然闭源”的现状为学术界和中小企业提供了前所未有的研究和应用可能性。本文将为你深入拆解 Inkling-Small。我们不会停留在新闻通稿式的介绍而是聚焦于三个核心问题MoE 架构到底是如何“四两拨千斤”的它如何用更少的计算成本撬动更大的模型容量Inkling-Small 的“多模态”能力具体体现在哪里是简单的图文描述还是能进行复杂的推理和创作作为一个开发者或研究者我该如何上手从环境搭建、模型运行到效果评测有哪些实际的坑和技巧如果你正在寻找一个既强大又相对“轻量”且能自由探索的多模态AI模型那么这篇文章将为你提供一份从原理到实践的完整指南。1. Inkling-Small 的核心价值为什么是它在深入技术细节之前我们必须先理解 Inkling-Small 出现的意义。它不是一个简单的模型更新而是代表了当前大模型发展的几个关键趋势的交叉点。第一从“暴力堆料”到“精细架构”的转变。早期的模型如 GPT-3采用的是Dense稠密架构。1750亿参数中每一个参数在每次前向传播时都会被激活和使用。这带来了极高的计算和内存开销。而MoE 架构的核心思想是“专才专用”。模型由许多个“子网络”专家组成一个路由网络Router会根据输入动态选择少数几个最相关的专家进行计算。对于 Inkling-Small虽然总参数量高达 276B但每次推理只激活约 12B 的参数。这相当于你拥有一个由数百位各领域专家组成的智库但每次咨询问题时只请出2-3位最对口的专家来解答效率自然大幅提升。第二多模态成为AI的“标配”能力。纯文本模型已经无法满足现实世界的需求。文档理解、智能客服、内容创作、教育辅助等场景天然需要结合视觉和语言信息。Inkling-Small 作为一个多模态模型其价值在于提供了统一的“理解-生成”框架。它不仅能回答关于图片的问题还能根据文字描述生成图像或者进行图文结合的创造性任务。第三开源与开放许可降低了创新门槛。Apache 2.0 协议是一个非常商业友好的开源协议。这意味着企业可以自由地使用、修改甚至商用基于 Inkling-Small 开发的系统而无需担心复杂的版权或付费问题。这对于创业公司、高校实验室和独立开发者来说是至关重要的。它使得前沿技术的探索不再被少数几家巨头垄断。所以Inkling-Small 适合谁AI 应用开发者希望构建具备多模态交互能力的应用如智能设计助手、教育工具、内容审核系统但受限于算力预算。机器学习研究者希望研究 MoE 架构的训练动态、多模态融合机制或以其为基础进行模型微调Finetuning。技术决策者在评估团队技术栈时需要一个在性能、成本和可控性上取得平衡的候选模型。接下来我们将穿透这些标签看看它的技术内核是如何工作的。2. 核心概念拆解MoE 与多模态要真正理解 Inkling-Small必须搞懂两个核心概念MoE和多模态学习。2.1 MoE混合专家系统如何实现“大而高效”你可以把传统的 Dense 模型想象成一个“通才”。它通过一个巨大的、固定的神经网络处理所有问题。无论输入是法律条文还是漫画对白它都动用全部“脑细胞”。这很强大但极其低效。MoE 模型则是一个“专家委员会”专家Expert模型内部包含多个相对较小的前馈神经网络FFN每个专家都在训练过程中倾向于擅长处理某一类数据或任务。在 Inkling-Small 中可能有成千上万个这样的专家。路由Router这是一个轻量级的网络层它的任务是为每个输入的 token文本的最小单元计算一个概率分布决定将这个 token 发送给哪几个专家处理。稀疏激活对于每个 token路由器只选择概率最高的前k个专家通常k2或4。只有被选中的专家才会被激活并进行计算其他专家处于“休眠”状态。这就是12B 激活参数的由来——它指的是每次前向传播时实际参与计算的参数总量。MoE 带来的核心优势计算效率大幅降低了单次推理的计算量FLOPs使得超大模型在有限算力下运行成为可能。模型容量总参数量可以做得非常大从而容纳更广泛的知识而不会同比例增加计算成本。任务专业化不同的专家可以隐式地学习到处理不同语言、不同领域知识的能力。MoE 面临的挑战训练不稳定专家之间容易出现“赢者通吃”即路由器总是倾向于选择少数几个专家导致其他专家得不到充分训练。通信开销在分布式训练中需要将不同的 token 路由到可能位于不同计算设备GPU的专家上引入额外的通信成本。负载均衡需要精心设计路由策略和辅助损失函数确保所有专家都能被均衡地使用。2.2 多模态学习文本与图像的“共同语言”多模态模型的目标是让机器能像人类一样综合处理来自不同感官如视觉、听觉的信息。Inkling-Small 聚焦于视觉-语言模态。其关键技术在于模态对齐统一表示空间无论是文本还是图像在输入模型前都会被转换成一系列向量Vector。文本通过分词器Tokenizer变成 token IDs 再嵌入Embedding图像通过一个视觉编码器如 ViT切割成图像块Patch并编码。最终文本 token 和图像 patch 都被映射到同一个高维语义空间里。跨模态注意力模型的核心——Transformer 注意力机制允许图像 patch 和文本 token 之间相互“关注”。例如当模型处理句子“一只坐在草地上的猫”时文本 token “猫”可以高度关注到图像中对应猫的那些 patch。这种双向注意力机制是实现图文理解、描述、问答的基础。生成能力作为一个生成模型Inkling-Small 不仅可以输出文本还能输出图像。这通常通过一个扩散模型Diffusion Model解码器来实现该解码器以模型内部的多模态表示作为条件逐步去噪生成高保真图像。多模态模型的典型任务视觉问答VQA给定一张图片和一个相关问题生成答案。图像描述Image Captioning为给定的图像生成一段文字描述。文本到图像生成Text-to-Image根据一段文字描述生成对应的图像。图文推理基于图文内容进行逻辑推理例如“如果拿走左边的杯子还剩几个水果”。理解了这些基础我们就可以开始动手让 Inkling-Small 在自己的机器上跑起来。3. 环境准备与模型获取在开始实验前请确保你的硬件和软件环境满足基本要求。由于 Inkling-Small 是一个大型模型对资源有一定需求。3.1 硬件与软件要求GPU这是必须的。建议至少拥有24GB 显存的 GPU如 NVIDIA RTX 4090, RTX 3090, A10, A100 等。虽然激活参数只有12B但加载276B的总参数需要大量显存并且需要空间存储中间激活值。多卡并行如2-4张卡会获得更好的体验。内存系统 RAM 建议64GB 或以上用于加载模型权重和数据处理。存储模型权重文件很大需要准备500GB 以上的可用磁盘空间用于下载、缓存和可能的转换。操作系统Linux如 Ubuntu 20.04/22.04是首选对深度学习框架支持最完善。Windows 通过 WSL2 也可行但可能遇到更多环境问题。Python版本 3.9 或 3.10。CUDA版本 11.8 或 12.1需与你的 GPU 驱动和后续安装的 PyTorch 版本匹配。3.2 创建虚拟环境与安装核心依赖强烈建议使用 Conda 或 venv 创建独立的 Python 环境避免包冲突。# 使用 conda 创建环境推荐 conda create -n inkling python3.10 -y conda activate inkling # 安装 PyTorch (请根据你的 CUDA 版本访问 https://pytorch.org/ 获取最新命令) # 例如对于 CUDA 12.1 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121 # 安装 Hugging Face Transformers 和 Accelerate (用于模型加载和分布式推理) pip install transformers accelerate # 安装额外的视觉和工具库 pip install pillow requests timm3.3 获取模型权重Inkling-Small 的权重开源在 Hugging Face Hub 上。我们可以使用git-lfs来克隆仓库或者直接通过 Transformers 库在线加载首次运行会自动下载。方式一使用 Hugging Face CLI推荐便于管理# 安装 git-lfs sudo apt-get install git-lfs # Ubuntu/Debian # 或 brew install git-lfs # macOS git lfs install # 克隆模型仓库此处的模型ID为示例请替换为官方实际ID # 假设官方仓库为https://huggingface.co/thinking-machines/inkling-small git clone https://huggingface.co/thinking-machines/inkling-small这将把整个模型可能包含多个分支和文件下载到本地inkling-small目录。方式二在代码中直接加载无需提前下载Transformers 库支持直接从 Hub 按需下载文件。这对于快速原型验证非常方便但第一次运行时会等待下载。from transformers import AutoModelForCausalLM, AutoProcessor model_id thinking-machines/inkling-small # 首次运行此代码会自动下载模型 model AutoModelForCausalLM.from_pretrained(model_id, torch_dtypetorch.float16, device_mapauto) processor AutoProcessor.from_pretrained(model_id)重要提示模型文件非常大可能超过200GB下载前请确认网络环境和磁盘空间。如果下载中断可以使用git lfs pull继续。4. 模型加载与推理流程详解成功获取模型后最关键的一步是如何正确地加载它并进行推理。由于模型巨大直接全精度加载到单卡几乎不可能我们必须利用一些技术来减少内存占用。4.1 高效加载策略半精度与设备映射现代大模型推理普遍采用float16半精度甚至bfloat16格式这能在几乎不损失精度的情况下将显存占用减半。同时device_map”auto”参数允许 Transformers 库自动将模型的不同层分配到可用的 GPU 和 CPU 内存上。import torch from transformers import AutoModelForCausalLM, AutoProcessor # 指定模型ID model_id thinking-machines/inkling-small # 加载处理器负责文本分词和图像预处理 processor AutoProcessor.from_pretrained(model_id) # 以半精度模式加载模型并自动分配设备 model AutoModelForCausalLM.from_pretrained( model_id, torch_dtypetorch.float16, # 使用半精度显著减少显存 device_mapauto, # 自动将模型层分配到多个GPU或CPU trust_remote_codeTrue # 如果模型需要自定义代码则需要此参数 ) # 将模型设置为评估模式 model.eval() print(模型加载完成)关键参数解释torch_dtypetorch.float16这是必须的。276B参数的模型如果用float32加载仅权重就需要超过 1TB 显存而float16只需一半。device_map”auto”这是 Hugging Faceaccelerate库提供的功能。它会分析你的硬件GPU数量、显存大小、CPU内存并尝试将模型层智能地分布上去。例如前几层放在 GPU0中间几层放在 GPU1最后几层和 embedding 层放在 CPU。这是运行超大规模模型的关键。trust_remote_codeTrue如果模型的定义使用了自定义的 PyTorch 模块非 Transformers 原生支持则需要此参数。对于 Inkling-Small 这类前沿模型很可能需要。4.2 准备多模态输入文本与图像Inkling-Small 的输入是一个包含图像和文本的“对话”或“指令”。处理器AutoProcessor会帮我们处理好一切。from PIL import Image import requests # 示例1从网络加载一张图片 url https://example.com/a_cat_on_grass.jpg # 替换为实际图片URL image Image.open(requests.get(url, streamTrue).raw) # 示例2从本地文件加载图片 # image Image.open(/path/to/your/image.jpg) # 构建一个多模态提示词 # 格式通常类似于“image\nUser: 请描述这张图片。\nAssistant:” # 具体格式需要参考模型的官方文档或示例 prompt 请详细描述这张图片中的场景。 # 注意实际的 prompt 模板可能更复杂可能包含特殊的图像标记如 image。 # 最可靠的方式是查看 processor 的 chat_template 属性或官方示例。 # 使用处理器处理输入 inputs processor( textprompt, # 文本指令 imagesimage, # PIL Image 对象 return_tensorspt # 返回 PyTorch 张量 ) # 将输入数据移动到与模型相同的设备上 inputs {k: v.to(model.device) for k, v in inputs.items()} print(输入数据准备完毕。)重要提醒多模态模型的输入格式Prompt Template非常关键。错误的格式可能导致模型无法理解你的意图。务必查阅 Inkling-Small 的官方文档或 Hugging Face 模型卡Model Card找到正确的对话格式。常见的格式可能是”image\\nHuman: {question}\\nAssistant:”或类似 Vicuna、LLaVA 的格式。4.3 执行生成推理准备好输入后我们就可以让模型进行生成。这里需要使用model.generate方法并设置合适的生成参数以平衡速度和质量。# 设置生成参数 generation_kwargs { max_new_tokens: 512, # 生成文本的最大长度 temperature: 0.7, # 控制随机性越低越确定越高越有创意 top_p: 0.9, # 核采样参数累积概率达到 top_p 的词汇中进行采样 do_sample: True, # 启用采样如果为 False 则使用贪婪解码 repetition_penalty: 1.1, # 重复惩罚避免生成重复内容 } # 在推理时不计算梯度以节省显存 with torch.no_grad(): # 生成输出 generated_ids model.generate(**inputs, **generation_kwargs) # 解码生成的 token IDs 为文本 # 注意processor 的 decode 方法会自动跳过输入部分只输出模型生成的部分 generated_text processor.batch_decode(generated_ids, skip_special_tokensTrue)[0] print(模型生成结果) print(generated_text)生成参数调优指南max_new_tokens根据任务设定。图像描述可以短一些如128故事生成则需要更长如1024。temperature对于事实性问答建议较低0.1-0.3对于创意写作可以调高0.7-1.0。top_p(nucleus sampling)与 temperature 配合使用通常 0.8-0.95 效果较好。do_sample如果设为False则使用贪婪搜索每次选概率最高的词生成结果确定但可能枯燥。True则引入随机性。repetition_penalty略微大于1的值如1.1可以有效抑制词语重复。5. 实战示例运行你的第一个多模态任务让我们通过一个完整的端到端示例将上述步骤串联起来完成一个**视觉问答VQA**任务。假设我们有一张图片meeting_room.jpg内容是一个会议室桌上有笔记本电脑、白板和马克杯。# 文件run_inkling_vqa.py import torch from PIL import Image from transformers import AutoModelForCausalLM, AutoProcessor def run_visual_qa(image_path, question): 使用 Inkling-Small 进行视觉问答 Args: image_path: 图片文件路径 question: 问题文本 # 1. 加载模型和处理器假设已下载到本地路径 ./inkling-small model_path ./inkling-small print(f正在从 {model_path} 加载模型...) processor AutoProcessor.from_pretrained(model_path) model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) model.eval() print(模型加载成功。) # 2. 准备输入 image Image.open(image_path).convert(RGB) # 构建符合模型期望的提示词。此处为示例格式请务必根据官方文档调整 # 常见的多模态提示格式可能包含 image 标记和角色定义。 prompt fimage\nHuman: {question}\nAssistant: inputs processor( textprompt, imagesimage, return_tensorspt ) inputs {k: v.to(model.device) for k, v in inputs.items()} # 3. 生成回答 print(f正在生成回答...) generation_kwargs { max_new_tokens: 150, temperature: 0.2, # VQA任务需要确定性较高的答案 do_sample: True, top_p: 0.9, } with torch.no_grad(): generated_ids model.generate(**inputs, **generation_kwargs) # 4. 后处理与输出 # 解码时我们需要提取 Assistant 部分之后的文本。 full_response processor.batch_decode(generated_ids, skip_special_tokensTrue)[0] # 简单的后处理找到 Assistant: 之后的内容 if Assistant: in full_response: answer full_response.split(Assistant:)[-1].strip() else: answer full_response # 如果格式不符返回全部 print(f\n问题{question}) print(f回答{answer}) return answer if __name__ __main__: # 使用示例 answer run_visual_qa( image_pathmeeting_room.jpg, question会议室里有哪些物品 )运行这个脚本python run_inkling_vqa.py预期输出可能类似于正在从 ./inkling-small 加载模型... 模型加载成功。 正在生成回答... 问题会议室里有哪些物品 回答图片显示了一个现代风格的会议室。中央有一张长条桌桌上放着一台打开的银色笔记本电脑、一个白色的马克杯以及一些散落的文件。房间的一侧有一块大的白板上面写有一些图表和文字。墙上有几幅抽象画。椅子是黑色的办公椅。这个示例展示了 Inkling-Small 如何将视觉信息会议室内的物品与语言理解识别并列举物品结合起来完成一个具体的任务。6. 进阶应用文本到图像生成除了理解图像Inkling-Small 作为多模态模型很可能也具备文本到图像的生成能力具体取决于模型设计。如果官方确认支持其使用模式可能与 Stable Diffusion 类似但指令遵循能力更强。以下是一个假设性的文本到图像生成代码框架实际 API 可能有所不同# 文件run_inkling_text_to_image.py (假设性示例) import torch from PIL import Image from transformers import AutoModelForCausalLM, AutoProcessor def generate_image_from_text(prompt): 根据文本描述生成图像此代码为概念示例实际调用方式需参考官方文档 model_path ./inkling-small processor AutoProcessor.from_pretrained(model_path) model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapauto, trust_remote_codeTrue ) model.eval() # 假设模型处理文本到图像时需要特殊的提示词前缀 full_prompt fGenerate an image: {prompt} inputs processor(textfull_prompt, return_tensorspt) inputs {k: v.to(model.device) for k, v in inputs.items()} with torch.no_grad(): # 假设模型有一个 generate_image 方法或通过特定生成参数控制 # 这里仅为示意实际生成图像可能是输出 latent codes 或直接调用内部扩散模型解码器 output model.generate(**inputs, guidance_scale7.5, num_inference_steps50) # 假设处理器能将模型输出解码为 PIL 图像 generated_image processor.decode_image(output[0]) return generated_image if __name__ __main__: image generate_image_from_text(A serene landscape with a lake and mountains at sunset.) image.save(generated_landscape.png) print(图像已保存为 generated_landscape.png)重要说明文本到图像生成的确切接口需要严格参考 Inkling-Small 的官方文档。上述代码是一个概念性框架实际调用可能涉及不同的 pipeline 或 API。7. 性能优化与常见问题排查运行一个 276B 参数的模型绝非易事。以下是你在实践中几乎一定会遇到的问题和优化策略。7.1 显存不足CUDA Out Of Memory这是最常见的问题。排查与解决思路问题现象可能原因排查方式解决方案加载模型时 OOM模型权重太大单卡放不下。观察nvidia-smi显存占用。1.使用device_map”auto”这是首选方案让accelerate自动分配模型到多GPU和CPU。2.启用 CPU 卸载在from_pretrained中设置offload_folder”offload”和offload_state_dictTrue将暂时不用的层移到CPU内存。3.使用内存更小的数据类型尝试torch_dtypetorch.bfloat16如果硬件支持或使用量化如 bitsandbytes 库的 8-bit/4-bit 量化。推理生成时 OOM输入序列太长或生成序列太长中间激活值爆显存。尝试缩短输入或max_new_tokens。1.减少批次大小确保inputs的 batch size 为 1。2.使用 KV Cache确保模型生成时使用了键值缓存避免重复计算。3.启用梯度检查点在加载模型时设置use_cacheFalse并启用gradient_checkpointingTrue主要用于训练推理时影响速度。4.分块处理长文本对于超长文本可以分段处理。量化加载示例使用 bitsandbytes 8-bit 量化pip install bitsandbytesfrom transformers import BitsAndBytesConfig import torch quantization_config BitsAndBytesConfig( load_in_8bitTrue, # 使用 8-bit 量化加载 llm_int8_threshold6.0, ) model AutoModelForCausalLM.from_pretrained( model_id, quantization_configquantization_config, # 传入量化配置 device_mapauto, trust_remote_codeTrue )注意量化会轻微影响模型精度但能极大减少显存占用约减少4倍。7.2 生成质量不佳或答非所问排查与解决思路问题现象可能原因解决方案回答完全无关输入提示词Prompt格式错误。仔细检查并严格按照官方示例的 prompt 模板。多模态模型的 prompt 通常非常严格包含特定的角色标记如image,Human:,Assistant:和换行符。回答模糊、笼统生成参数temperature太高或top_p不合适。对于事实性任务降低temperature(如 0.1) 并设置do_sampleFalse贪婪解码。对于创意任务可以适当调高。生成内容重复缺乏重复惩罚。增加repetition_penalty参数的值例如设为 1.2。无法理解图像内容图像预处理可能有问题或模型视觉编码器未正确加载。1. 确保图像是 RGB 模式且分辨率在模型支持范围内如 224x224, 336x336。2. 检查处理器processor是否包含了正确的图像预处理如CLIPImageProcessor。7.3 推理速度慢MoE 模型虽然激活参数少但路由逻辑和专家间的数据调度会带来额外开销。优化建议使用更快的 GPUA100/H100 的 Tensor Core 对 FP16/BF16 计算有巨大加速。确保使用半精度torch_dtypetorch.float16必不可少。批处理Batching如果有多张图片或多个问题尽量组成一个 batch 输入能极大提升吞吐量。但要注意显存限制。使用 Flash Attention如果模型和你的 GPU如 Ampere 架构之后支持启用 Flash Attention 可以加速注意力计算。这通常需要在编译 Transformers 库时开启特定选项或使用像optimum这样的优化库。8. 最佳实践与工程化建议如果你想将 Inkling-Small 用于实际项目或深入研究以下建议能帮你走得更稳。8.1 模型版本与文档管理锁定版本在requirements.txt或环境配置中明确记录你使用的transformers,torch以及模型仓库的 commit hash。大模型更新可能带来不兼容的变更。仔细阅读 Model CardHugging Face 上的模型卡Model Card是信息宝库通常会包含准确的 Prompt 格式训练数据和能力边界已知的局限性和偏见最低硬件要求使用许可Apache 2.08.2 数据处理与提示工程图像预处理标准化建立统一的图像预处理流程包括调整大小、归一化、通道转换等。使用模型自带的processor是最安全的方式。构建提示词模板库将不同任务VQA描述创作推理的、经过验证有效的提示词模板保存下来形成团队的“提示词工程”知识库。系统指令System Prompt尝试在对话开始前加入系统指令来引导模型行为例如“你是一个有帮助且准确的视觉助手。”这有时能显著提升回答质量。8.3 生产环境部署考量服务化考虑使用FastAPI或Triton Inference Server将模型封装成 HTTP/gRPC 服务便于其他系统调用。监控与日志记录模型的推理延迟、显存使用率、输入输出长度以及用户反馈用于后续的性能分析和模型迭代。成本估算MoE 模型虽然激活参数少但加载全部专家权重依然需要大量存储和内存。估算好存储、内存和 GPU 实例的长期成本。安全与合规对用户上传的图片和生成的文本内容进行必要的安全过滤和审核避免产生有害内容。8.4 后续探索方向微调Fine-tuning在特定领域的数据集如医疗影像报告、电商产品图上对 Inkling-Small 进行微调可以使其在该领域表现更专业。需要研究其是否支持 LoRA 等参数高效微调方法。模型压缩探索对 MoE 模型进行剪枝、蒸馏或更激进的量化如 4-bit以进一步降低部署门槛。多模态检索增强生成RAG将 Inkling-Small 作为理解器结合外部知识库如图文数据库构建能够回答复杂、细粒度问题的系统。Inkling-Small 的发布为社区提供了一个绝佳的、可深入探究的 MoE 多模态模型实例。它验证了通过稀疏化架构来扩展模型能力的可行性路径。对于开发者而言真正的价值不在于运行一个 demo而在于理解其架构精髓并思考如何将这种“大容量、高效率”的设计思想应用到自己的项目中。从今天开始下载模型运行第一个示例观察路由器的选择分析不同专家对输入的响应。在这个过程中你收获的将不仅是如何使用一个工具更是对下一代 AI 模型架构的切身感知。
返回列表