ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【大模型RAG生成式AI开发实战】《大模型RAG生成式AI开发实战》_39.[第4章 多模态RAG] 多模态RAG性能优化:模型选择和推理加速

【大模型RAG生成式AI开发实战】《大模型RAG生成式AI开发实战》_39.[第4章 多模态RAG] 多模态RAG性能优化:模型选择和推理加速 你的多模态RAG不是慢在模型上而是慢在瞎选和蛮算上一份从Embedding选型到推理引擎调优的避坑提速完全指南看完至少省下一半GPU预算。多模态RAG性能优化模型选择推理加速模型选择推理加速索引与全链路Embedding选型视觉编码器VLM主干量化与蒸馏KV-Cache优化动态批处理图文混合索引异步流水线文字目录要点一Embedding模型选型不是越大越好而是越配越好要点二视觉编码器与VLM主干分辨率与架构的隐形博弈要点三量化与知识蒸馏给模型瘦身的科学姿势要点四KV-Cache与显存管理别让显存成了性能天花板要点五Continuous Batching与请求调度榨干GPU的最后一滴算力要点六多模态索引与流水线解耦从串行阻塞到并行飞起嗨大家好呀我是你的老朋友精通代码大仙。接下来我们一起学习 《大模型RAG生成式AI开发实战》39.[第4章 多模态RAG] 多模态RAG性能优化模型选择和推理加速。咱们程序员圈里有句话特别真实“小孩才做选择大人全都要。” 但放在多模态RAG这件事上如果你不做取舍、不讲策略搞不定既要效果又要速度的平衡那最后的结果很可能是一个都要不到。很多新手同学刚搭起一个能跑通的多模态RAG demo就急着上线结果发现 GPU 风扇转得跟直升机似的QPS 却低得可怜用户问一个问题要等五秒以上体验直接崩盘。你是不是也这样看着满屏的CUDA out of memory和高达几秒的延迟心里拔凉拔凉的甚至开始怀疑是不是自己的显卡太垃圾别慌今天咱们就把这事儿掰开了、揉碎了讲清楚。性能优化不是玄学而是一门把钱花在刀刃上的工程手艺。接下来这六个关键要点都是我从一个个坑里爬出来后总结的干货。坐稳了咱们发车。要点一Embedding模型选型不是越大越好而是越配越好点题多模态RAG的第一步就是把图片、文本甚至音频变成机器能读懂的向量。这个翻译官就是多模态Embedding模型。选得好后续检索事半功倍选错了后面接再强的生成模型也是白搭。很多新手在这里有一个根深蒂固的误区参数越大、名气越响的模型效果一定越好。痛点分析我见过太多同学一上来就搬出 OpenAI 的 CLIP ViT-L/14或者最大号的 SigLIP觉得大即是正义。想法可以理解但坑也埋得稳稳的。第一个坑是场景错配。CLIP 这种通用模型它见过的数据是互联网上的通用图文对你拿它去检索专业领域的细粒度图片比如医疗影像里的 CT 切片、工业质检里的零件瑕疵图、电商领域的 SKU 商品图它的语义粒度根本对不上。张三做过一个电商商品图检索系统用 CLIP ViT-L/14想搜红色连衣裙结果 Top3 里混进来一个红色消防栓。为啥因为通用模型学到的红色是一个宏观概念它不懂电商场景下的款型、材质、领型这些细粒度属性。第二个坑是资源错配。ViT-L/14 这种级别的大 Embedding 模型单卡显存占用能干到 12GB 以上推理延迟高QPS 根本上不去。你本来想做个高并发的检索服务结果 Embedding 服务成了瓶颈GPU 全被它吃光了后面的大模型连汤都喝不上。# 新手的暴力选型只看名字带Large就冲fromtransformersimportCLIPModel,CLIPProcessor modelCLIPModel.from_pretrained(openai/clip-vit-large-patch14).cuda()processorCLIPProcessor.from_pretrained(openai/clip-vit-large-patch14)# 在自己的工业零件数据集上直接提取特征# 结果Top5 准确率不到 40%单卡 QPS 只有 5显存爆了解决方案/正确做法Embedding 选型本质上是相亲合适比优秀重要一百倍。第一步先认清你的场景。如果是通用图文检索SigLIP、EVA-CLIP-CLIP 这些确实不错但如果是垂直领域优先去找领域专用模型。比如做时尚电商有 Fashion-CLIP做中文多模态有 BGE-VL 系列做文档理解有 ColPali、ColQwen 这种 Late Interaction 模型。这些模型要么在垂直数据上预训练过要么架构上更适合细粒度对齐。第二步轻量化优先微调跟上。很多场景下一个 300MB 的小模型经过你的数据微调后检索效果能吊打 3GB 的通用大模型。不要迷信零样本能力RAG 系统里最不缺的就是你自己的业务数据拿它来做个对比学习微调收益极高。# 聪明人的选型按场景匹配轻量可微调fromsentence_transformersimportSentenceTransformer# SigLIP-base 在多数任务上已经足够且速度快 3 倍以上modelSentenceTransformer(sentence-transformers/siglip-base-patch16-224)# 如果有垂直数据接一段对比学习微调# 训练后在自己的测试集上评估 Recall5 和 QPS# 结果显存降到 3GBQPS 提到 50准确率反而涨了 15%这样做的好处显而易见省下的显存可以留给后面的生成模型省下的延迟可以直接转化为用户体验。而且维护一个轻量模型后续迭代、部署、横向扩容都轻松得多。小结Embedding 选型不是选美比赛是相亲。别只看参数量和论文标题要看它懂不懂你的业务能不能在你的硬件上跑得欢。要点二视觉编码器与VLM主干分辨率与架构的隐形博弈点题图片进入大模型的眼睛全靠视觉编码器Vision Encoder。选什么骨干网络、喂多高分辨率、产生多少视觉 Token这三个因素像一张看不见的网直接把下游 VLM 的推理速度和理解能力捆绑死了。新手往往只关注 LLM 部分的参数量却忽略了视觉端才是拖慢推理的隐形杀手。痛点分析最普遍的误区叫**“分辨率崇拜”**。很多人觉得图片分辨率越高模型看得越清楚回答就越准。于是 224x224 的不敢用非要上 336x336甚至 448x448、672x672。但他们没算过一笔账在 ViT Patch Size14 的情况下一张 336x336 的图片会产生 (336/14)^2 576 个视觉 Token如果拉到 672x672就是 2304 个 Token。这什么概念LLM 处理这些视觉 Token 的计算量和显存占用是跟着 Token 数线性甚至平方级增长的。你的 Context Window 本来能塞 5 篇检索回来的文档结果一张大图直接占掉一半文本没地方放了生成速度还暴跌。李四就踩过这个坑。他的多模态 RAG 处理 PDF 文档截图用了 LLaVA-1.5 的 336x336 配置。结果一张满屏表格产生 500 多个视觉 Token加上检索回来的文本和 Prompt输入长度直接超长。TPOTTime Per Output Token从 50ms 涨到 200ms用户每等一个字都像过了一年。而且他还分不清 ViT、ConvNeXt、SAM 这些骨干网的特性只觉得能用就行结果选的模型视觉端又重又慢LLM 部分反而成了陪衬。# 痛点的典型代码一股脑高分辨率所有图一视同仁fromtransformersimportLlavaNextProcessor,LlavaNextForConditionalGeneration processorLlavaNextProcessor.from_pretrained(llava-hf/llava-v1.6-34b-hf)# 不管输入是简单图标还是复杂表格全部强制 resize 到 336x336inputsprocessor(images[image1,image2,image3],return_tensorspt,paddingTrue)# 小图标也被拉成 336x336产生大量无意义 Token解决方案/正确做法核心策略是按需分配动态压缩。现在的先进模型比如 Qwen2-VL、InternVL2、Mini-Monkey都支持动态分辨率。简单说系统会根据图片本身的复杂度和尺寸自动决定切成几块、每块多大而不是暴力拉伸到固定尺寸。简单图标可能只用 224x224 甚至更低复杂表格才启用高分辨率。这样视觉 Token 的平均数量能下降 30%-50%速度直接起飞。其次关注视觉投影层的设计。很多早期 VLM 是视觉 Token 直接硬塞进 LLMToken 数完全由分辨率决定。而新架构里Perceiver Resampler、Pixel Shuffle、或 Q-Former 这类压缩层可以把几百个视觉 Token 压缩到几十个甚至几个让 LLM 的负担大幅减轻。如果你的业务里图片信息密度不高比如 LOGO 识别、简单图标理解优先选带 Token 压缩机制的模型。# 正确姿势拥抱动态分辨率fromtransformersimportQwen2VLForConditionalGeneration,AutoProcessor modelQwen2VLForConditionalGeneration.from_pretrained(Qwen/Qwen2-VL-7B-Instruct,torch_dtypeauto,device_mapauto)processorAutoProcessor.from_pretrained(Qwen/Qwen2-VL-7B-Instruct)# Qwen2-VL 内部会根据原图尺寸计算最优 Token 数# 简单图可能只有 64 个视觉 Token复杂表格自动切分到 448x448# 实测视觉 Token 平均减少 40%推理速度提升 2 倍准确率不降反升小结视觉编码器的核心矛盾是看得清和算得快。拒绝暴力高分辨率拥抱动态分辨率与 Token 压缩你的 VLM 才能真正眼明手快。要点三量化与知识蒸馏给模型瘦身的科学姿势点题7B 的 VLM 在单卡 A100 上跑已经有点吃力34B 的更是直接劝退。但业务要求必须快、必须省显存怎么办量化和蒸馏就是两大科学减肥法。问题是很多新手要么不敢用要么用得太粗暴直接把模型性能给减残了。痛点分析第一个误区是闻量化色变。有些同学觉得 INT8、INT4 就是偷工减料精度肯定崩。其实现代量化技术AWQ、GPTQ、SmoothQuant已经相当成熟但很多新手不知道怎么针对多模态模型做分层量化。多模态模型里视觉编码器对数值精度极其敏感因为它的特征是浮点矩阵乘法累加出来的低 bit 很容易把颜色、纹理、空间关系的细节给抹平。王五就吃过这个亏他把 Qwen-VL-Chat 7B 用 GPTQ 做了暴力 INT4 量化LLM 和 Vision Encoder 一起砍。结果模型体积确实减半了但做 RAG 增强问答时把图表里的蓝色曲线识别成绿色曲线把数字3.14读成3.11。因为视觉端的激活值分布本来就很分散低 bit 量化直接把边界特征给吃了。第二个误区是不知道蒸馏该蒸哪。多模态模型的知识不光在 LLM 里还在视觉-语言对齐层Projection Layer里。你拿 GPT-4V 生成一堆答案然后只去蒸馏学生模型的文本生成能力而不管图片怎么映射到文本空间那学生还是睁眼瞎。# 错误示范暴力全量化视觉文本一起砍# 用 AutoGPTQ 加载后直接推理fromauto_gptqimportAutoGPTQForCausalLM modelAutoGPTQForCausalLM.from_quantized(Qwen-VL-Chat-7B-GPTQ-int4,devicecuda:0)# 推理时发现颜色错乱、图表数字识别错误、细粒度图文对齐失效解决方案/正确做法正确的量化策略叫**“分区保护”**。视觉编码器尽量保持 FP16 或至少 INT8而对计算量大、鲁棒性强的 LLM 部分做 INT4/INT8 量化。AWQActivation-aware Weight Quantization因为考虑了激活值分布对多模态场景更友好。在实际部署中vLLM、LMDeploy 这些推理框架都支持加载 AWQ/GPTQ 模型而且会自动处理分区加载。如果你不想自己折腾量化更省心的办法是直接选用已经蒸馏好的轻量 VLM。比如 TinyLlava、MobileVLM、Bunny 系列它们通常基于 Phi-2、StableLM 这类小 LLM配合轻量视觉编码器如 SigLIP-base在 2B-3B 参数规模下能达到 7B 模型 85%-90% 的能力。多模态蒸馏的关键是要用强教师模型GPT-4V、Qwen-VL-Max生成高质量的指令微调数据然后在训练学生模型时不光蒸馏文本输出还要对齐视觉到文本的映射空间。# 正确姿势LLM 量化视觉保精度或直接用小模型fromvllmimportLLM# AWQ 量化只作用于 LLM视觉编码器内部自动保持 FP16llmLLM(modelQwen2-VL-7B-Instruct-AWQ,quantizationawq,dtypeauto,gpu_memory_utilization0.85)# 或者直接用 Bunny-3B 这类蒸馏小模型# 推理速度快 3 倍显存占用 1/3标准 benchmark 达 7B 模型 90% 性能小结量化不是无脑砍精度而是哪里耐砍砍哪里蒸馏不是照抄答案而是偷师学艺取其精华。保护视觉端的敏感神经你的小模型也能有大智慧。要点四KV-Cache与显存管理别让显存成了性能天花板点题做过 LLM 推理的同学都知道模型参数只占显存的一部分真正的大户是 KV-Cache。在多模态 RAG 里这个矛盾更尖锐视觉 Token 加长文本 Token再加上检索回来的上下文KV-Cache 能把你的 A100 直接撑爆。不会管显存就像开着法拉利却堵在早高峰——马力再强也白搭。痛点分析新手写推理服务最常见的姿势是直接调用 HuggingFace 的model.generate()。这种方式的 KV-Cache 管理非常原始要么随用随扔无法复用历史对话要么连续分配产生大量显存碎片。当你想同时服务多个用户时每个请求都要占一大块连续显存存 Key 和 Value结果来了三四个请求就 OOM只能串行处理。赵六就遇到过这种事他用 vLLM 跑多模态 RAG但没去调gpu_memory_utilization默认 0.9。多模态场景下图片经过 Vision Encoder 后的 feature 矩阵先占一大块再加上暴涨的 KV-Cache服务一压测就崩。他原以为是 7B 模型太大想升级硬件其实是显存管理没入门。另一个隐形杀手是注意力架构。如果你用的是传统的 MHAMulti-Head Attention每个头都有独立的 K 和 V显存占用随头数线性增长。而 MQAMulti-Query Attention和 GQAGrouped-Query Attention能大幅压缩这部分开销。很多新手选型时不看这个细节选了老架构的模型白白浪费显存。# 痛点代码HF 原生推理KV-Cache 无管理fromtransformersimportAutoModelForVision2Seq modelAutoModelForVision2Seq.from_pretrained(some-vlm).cuda()# 每次 generate 都重新分配 KV-Cache无法共享无法分页outputsmodel.generate(**inputs,max_new_tokens512)# 并发一高就 OOMGPU 利用率不到 30%解决方案/正确做法modern 的解法就两个词PageAttention和GQA。PageAttention 是 vLLM 提出的核心创新它把 KV-Cache 从连续的显存块改成非连续的页Page像操作系统的虚拟内存一样按需分配、动态映射。这样显存碎片几乎为零同一个 batch 里能塞的请求数翻几倍。vLLM、SGLang、LMDeploy 都已经内置了 PageAttention 或改进版的 RadixAttention。在多模态场景下你还需要特别关注max_model_len和max_num_batched_tokens的配置。视觉 Token 往往很长如果设得太保守GPU 算力用不满设得太激进显存又扛不住。建议根据你的平均输入图片尺寸和文本长度实测一个甜点值。另外选型时优先挑支持 GQA/MQA 的 VLM比如 Qwen2-VL、LLaMA 3.2 Vision、InternLM-XComposer2它们的 KV-Cache 占用只有传统 MHA 的 1/8 到 1/4。# 正确姿势vLLM PageAttention 合理显存预算fromvllmimportLLM,SamplingParams llmLLM(modelQwen2-VL-7B-Instruct,tensor_parallel_size1,gpu_memory_utilization0.85,# 留出 15% 缓冲防止多模态 feature 爆显存max_model_len4096,# 根据业务实测调整enforce_eagerFalse# 启用 CUDA Graph进一步降低延迟)sampling_paramsSamplingParams(temperature0.2,max_tokens512)# 同样 A100并发从 4 路提升到 32 路TTFT 从 2s 降到 300ms小结KV-Cache 不是负担是没被管好的资源。PageAttention 加上 GQA就是多模态 RAG 推理的显存管家。要点五Continuous Batching与请求调度榨干GPU的最后一滴算力点题你的 GPU 算力很贵每一秒闲置都是在烧钱。但传统的推理方式却让 GPU 把大量时间浪费在等数据和等队友上。Continuous Batching 和智能调度就是让你的算力从单线程升级到高并发的关键。痛点分析最经典的反模式叫静态批处理Static Batching。服务层攒够 8 个请求才打包发给模型如果第 8 个请求来得慢前 7 个就得干等着。更离谱的是一个 batch 里各个请求的生成长度不一样短的早就做完了却必须等最长的那个一起收尾GPU 空转。多模态场景下还有额外暴击不同请求的图片分辨率天差地别。钱七的系统里有人传了 1MB 的 8K 截图有人传了几十 KB 的小图标。静态 batching 为了张量对齐会把所有图片 padding 到最大尺寸小图标明明只需要 64 个视觉 Token硬被 padding 到 1024七分之八的计算都喂了空气。另一个坑是长请求堵塞。一个用户扔了本 50 页的 PDFPrefill 阶段要算好几秒。如果是传统的一个 batch 跑完再跑下一个后面所有用户都得排队等这位大爷算完P99 延迟直接爆炸。# 静态批处理的伪代码低效且浪费defstatic_batch_infer(requests):# 攒够 batch_size 才发车whilelen(buffer)8:wait()# 为了对齐所有图片 padding 到最大分辨率padded_images[pad_to_max(req.image)forreqinbuffer]# 小图也按大图算大量无效计算outputsmodel.generate(padded_images)解决方案/正确做法modern 推理框架vLLM、TGI、SGLang都支持Continuous Batching也叫 In-flight Batching。它的核心思想是新请求随时插进正在跑的 batch先完成的随时撤。GPU 永远有活干不会有等齐人的空窗期。再配合Chunked Prefill把长请求的 Prefill 阶段拆成一小块一小块跟 Decode 阶段交错执行一个长请求再也堵不住整条路了。在多模态 RAG 里还有一层优化叫异步预处理。图片的 resize、normalize、OCR 这些操作别放在 GPU 主线程里干。扔给 CPU 的线程池或者独立的预处理服务处理完了再把干净的张量喂给 GPU。这样 GPU 只做它最擅长的矩阵乘法不被图像解码拖累。# 正确姿势vLLM AsyncLLMEngine Chunked PrefillfromvllmimportAsyncLLMEngine,AsyncEngineArgs engine_argsAsyncEngineArgs(modelQwen2-VL-7B-Instruct,enable_chunked_prefillTrue,# 长请求不堵路max_num_batched_tokens2048,# 控制 batch 粒度max_num_seqs64# 最大并发序列数)# 图片预处理异步化不占用 GPU 主线程# 实测峰值吞吐量从 12 req/s 提升到 85 req/sP99 延迟下降 60%小结GPU 的算力很贵别让它在等数据和等队友上浪费生命。Continuous Batching 加上异步预处理才能让每一毫秒的算力都花在刀刃上。要点六多模态索引与流水线解耦从串行阻塞到并行飞起点题RAG 的全链路延迟有时候最大的瓶颈不在生成而在找的过程和传的过程。多模态索引怎么建、流水线怎么串决定了你的系统能不能从 demo 级别跃升到生产级别。痛点分析很多新手做多模态 RAG直接照搬纯文本那套图片扔给 CLIP 出一个向量文本扔给 BERT 出一个向量然后只跑向量检索。这套打法有两个致命伤。第一语义粒度太粗。一张 PDF 整页截图只出一个向量用户问第三段说的销售额是多少召回的却是整页向量噪声里裹着金子生成模型根本找不着北。第二检索手段单一。遇到找一张红色圆形按钮的截图这种带颜色、形状、位置的细粒度需求纯向量检索完全抓瞎因为它学的是语义相似度不是视觉属性。孙八就栽在这里。他的系统处理 10MB 的 PDF先整页转图片再整张图扔给 CLIP一页一个向量。用户问细节问题召回的上下文全是整页噪声准确率惨不忍睹。而且他的架构是单体式上传→OCR→Embedding→入库→检索→生成全在一个进程里串行。用户上传一张图端到端等 5 秒以上数据库阻塞、模型阻塞、文件 IO 阻塞全部搅在一起。# 痛点架构单体式串行处理defhandle_request(image):textocr(image)# 阻塞 1svecembedding(image)# 阻塞 500msstore_to_db(vec)# 阻塞 200mscontextretrieve(vec)# 阻塞 100msanswergenerate(context)# 阻塞 3sreturnanswer# 总延迟 5s任何一步卡住全完解决方案/正确做法检索层要升级到混合检索。不要只依赖向量要加入属性过滤颜色、标签、文档页码、关键词检索BM25、甚至多向量列图片一个向量、文本一个向量、表格结构化数据单独存。文档类场景先经过布局分析Layout Analysis把 PDF 切成段落、表格、图片块分别建索引。图片块用多模态 Embedding文本块用 BGE-M3 这类支持稀疏稠密多语言的模型表格走专用 Parser 转成 HTML/Markdown 再入向量库。召回时多路齐发重排序Rerank阶段再精排。架构层要做微服务解耦。用消息队列Redis Stream、RabbitMQ、Kafka把流水线拆开上传服务→预处理服务→OCR 服务→向量化服务→入库服务各管一段异步进行。用户查询时走独立的高并发检索链路和入库链路完全隔离。这样系统吞吐不再受最慢环节拖累而且可以单独扩容瓶颈节点。# 正确架构混合索引 异步流水线# 1. 布局分析切分文档Unstructured / PP-Structurechunkslayout_analysis(pdf_page)# 切出段落、表格、图片# 2. 多路向量入库# 文本块 - BGE-M3支持稀疏稠密# 图片块 - SigLIP / ColQwenLate Interaction细粒度对齐# 表格块 - 结构化数据 文本混合# 3. 检索时多路召回 Rerank# 向量召回 Top20 BM25 召回 Top20 - Cross-Encoder 重排 - Top5 送入 VLM# 4. 微服务异步解耦端到端延迟从 5s 降到 1.2s支持百倍并发扩容小结检索是 RAG 的地基流水线是 RAG 的血管。从单线程思维升级到分布式混合检索你的系统才能真正扛住生产流量。写在最后看到这里你应该发现了多模态 RAG 的性能优化从来不是某一个银弹能搞定的。它是一场从模型选型、架构设计到推理工程的全链路战役。Embedding 选错了后面全白搭视觉分辨率暴力拉升LLM 直接喘不上气量化不分区模型变色盲KV-Cache 不管理A100 也白给没有 Continuous BatchingGPU 总在干等索引和流水线不拆解并发一上来就全线崩盘。但好在这些坑都是有人趟过的。你不需要从零开始摸索只要记住今天这六个要点场景匹配优先、动态分辨率、分区量化、PageAttention、Continuous Batching、混合检索异步解耦。把这六张牌打出去你的多模态 RAG 至少能从能跑进化到跑得又快又省。编程之路不易但每一步成长都算数。多模态这阵风才刚刚刮起来现在把这些底层功夫扎牢半年后你会感谢今天没偷懒的自己。保持好奇持续动手你也能成为那个在团队里一言九鼎、指点江山的技术大腿。加油咱们下篇见关注私信备注“资料代找获取”全网计算机学习资料代找例如:《课程2026 年多模态大模型实战训练营》《课程AI 大模型工程师系统课程 (22 章完整版 持续更新)》《课程AI 大模型系统实战课第四期 (2026 年开课 持续更新)》《课程2026 年 AGI 大模型系统课 23 期》《课程2026 年 AGI 大模型系统课 21 期》《课程AI 大模型实战课 8 期 (2026 年 2 月最新完结版)》《课程AI 大模型系统实战课三期》《课程AI 大模型系统课程 (2026 年 2 月开课 持续更新)》《课程AI 大模型全阶课程 (2025 年 12 月开课 2026 年 6 月结课)》《课程AI 大模型工程师全阶课程 (2025 年 10 月开课 2026 年 4 月结课)》《课程2026 年最新大模型 Agent 开发系统课 (持续更新)》《课程LLM 多模态视觉大模型系统课》《课程大模型 AI 应用开发企业级项目实战课 (2026 年 1 月开课)》《课程大模型智能体线上速成班 V2.0》《课程JavaAI 大模型智能应用开发全阶课》《课程PythonAI 大模型实战视频教程》《书籍软件工程 3.0: 大模型驱动的研发新范式.pdf》《课程人工智能大模型系统课 (2026 年 1 月底完结版)》《课程AI 大模型零基础到商业实战全栈课第五期》《课程Vue3.5Electron 大模型跨平台 AI 桌面聊天应用实战 (2025)》《课程AI 大模型实战训练营 从入门到实战轻松上手》《课程2026 年 AI 大模型 RAG 与 Agent 智能体项目实战开发课》《课程大模型训练营配套补充资料》
返回列表