树莓派5集群部署DeepSeek R1:低成本边缘AI分布式推理实践 1. 项目概述与核心思路拆解最近在折腾一个挺有意思的实验用4台树莓派5组了个小集群跑起了DeepSeek R1模型。这事儿听起来有点“疯狂”毕竟树莓派5的性能和正经的服务器GPU比起来差距不是一点半点。但恰恰是这种“以小博大”的尝试让我对分布式推理、边缘计算以及模型部署的灵活性有了更深的理解。这个项目的核心不是追求极致的推理速度而是探索一种低成本、高可扩展性的轻量级AI部署方案看看在资源极其受限的边缘设备上我们能把大模型玩到什么程度。DeepSeek R1是DeepSeek最新推出的一个推理优化模型它本身在参数规模和计算效率上做了权衡目标就是在更小的算力上获得可用的推理能力。而树莓派5作为一款价格亲民、功耗极低、接口丰富的单板计算机其搭载的Broadcom BCM2712处理器四核Cortex-A76和VideoCore VII GPU虽然不能和英伟达的显卡相提并论但处理一些经过优化的轻量级模型推理任务已经具备了初步的可能性。单台树莓派5跑大模型肯定是捉襟见肘的所以思路很自然就转向了分布式——把计算任务拆开分给多台设备同时处理最后再汇总结果。这个项目的价值在于它为我们提供了一种思路当没有强大的中心化算力时如何利用身边大量闲置的、低功耗的设备不仅仅是树莓派也可以是旧手机、开发板等组成一个“算力网络”协同完成一些复杂的AI任务。这对于物联网、教育实验、原型验证、甚至某些对延迟敏感但预算有限的边缘AI场景都有一定的参考意义。接下来我就把这次从硬件准备、环境搭建、分布式框架选型到最终模型部署和测试的完整过程以及踩过的各种坑详细拆解一遍。2. 硬件准备与集群网络架构2.1 树莓派5选型与基础配置我这次用的是4台树莓派5 8GB版本。选择8GB主要是考虑到大模型参数和中间激活值对内存的占用。虽然R1是优化后的模型但在推理过程中尤其是进行一些长文本生成时内存压力依然不小。4GB版本可能会在运行稍大一点的批次或较长序列时频繁触发交换严重影响性能。每台树莓派5我都配了一个官方推荐的主动散热风扇套件因为持续的高负载计算会让SoC温度飙升过热降频会直接导致性能断崖式下跌。电源用的是官方推荐的27W USB-C PD电源确保供电稳定充足。存储方面我为每台设备配备了一张128GB的A2级别的MicroSD卡。A2级别对于随机读写性能有优化能在一定程度上改善系统响应和模型加载速度。当然如果有条件使用USB 3.0接口的外接SSD会更好但为了控制成本和保持设备的“纯粹性”这次统一用了高速SD卡。此外还需要准备一个千兆网络交换机以及4根网线。网络是分布式集群的血液其带宽和延迟直接决定了任务拆分和结果聚合的效率。系统安装我选择了64位的Raspberry Pi OS Lite无桌面环境。对于服务器用途图形界面完全是累赘会白白占用宝贵的内存和CPU资源。通过Raspberry Pi Imager工具刷写系统镜像非常方便记得在刷写前就通过该工具的“高级设置”预先开启SSH、设置好主机名如raspberrypi-01到raspberrypi-04、Wi-Fi和国家设置虽然我们主要用有线但备用。首次启动后通过SSH登录第一件事就是执行sudo apt update sudo apt upgrade -y进行系统更新。注意树莓派5的默认用户依然是pi但为了安全建议立即修改默认密码或者更好的是创建一个新的专用用户并赋予sudo权限然后禁用pi用户的SSH登录。2.2 集群网络与主机互信配置集群的所有节点必须处于同一个局域网段并且能够通过主机名互相访问。我规划的网络拓扑很简单4台树莓派5全部用网线连接到千兆交换机上我的开发笔记本电脑也接入同一个交换机方便管理和调试。交换机不需要任何特殊配置。首先为每台树莓派设置静态IP地址或者至少在路由器上为它们的MAC地址分配固定的DHCP租约。这是为了确保每次重启后IP不变方便后续配置。编辑/etc/dhcpcd.conf文件在末尾添加类似如下配置以raspberrypi-01为例假设网关是192.168.1.1interface eth0 static ip_address192.168.1.101/24 static routers192.168.1.1 static domain_name_servers192.168.1.1 8.8.8.8其他节点依次设置为.102,.103,.104。修改后重启网络服务或直接重启设备。接下来是关键的一步配置所有节点之间的SSH免密登录。这是分布式框架如Ray、PyTorch Distributed能够无缝在节点间启动进程的基础。在其中一个节点上我选raspberrypi-01作为主节点生成SSH密钥对ssh-keygen -t rsa一路回车即可。然后将公钥复制到所有节点包括自己ssh-copy-id piraspberrypi-01 ssh-copy-id piraspberrypi-02 ssh-copy-id piraspberrypi-03 ssh-copy-id piraspberrypi-04过程中需要输入各节点的密码。完成后尝试从raspberrypi-01SSH到其他节点应该可以直接登录无需密码。为了进一步方便可以在主节点的~/.ssh/config文件中添加别名Host node1 HostName raspberrypi-01 User pi Host node2 HostName raspberrypi-02 User pi ... 以此类推最后为了确保所有节点可以通过主机名互相解析有两种方法一是在路由器或局域网内搭建一个简单的DNS服务器更简单的方法是在每台树莓派的/etc/hosts文件中添加所有节点的IP和主机名映射。我在每台设备上都编辑了/etc/hosts添加了如下行192.168.1.101 raspberrypi-01 node1 192.168.1.102 raspberrypi-02 node2 192.168.1.103 raspberrypi-03 node3 192.168.1.104 raspberrypi-04 node4这样无论在哪个节点都可以直接用node1,node2等主机名访问其他节点了。网络基础至此搭建完毕。3. 软件环境与分布式框架部署3.1 Python与基础依赖安装树莓派OS自带的Python版本可能较旧。我们需要安装较新版本的Python并搭建一个独立的虚拟环境避免污染系统环境。首先安装编译工具和必要的库sudo apt install -y build-essential tk-dev libncurses5-dev libncursesw5-dev libreadline-dev libdb5.3-dev libgdbm-dev libsqlite3-dev libssl-dev libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev libffi-dev然后从Python官网下载源码编译安装。为了节省时间我选择了Python 3.10.13这个相对稳定且兼容性好的版本。不建议在树莓派5上盲目追求最新版本。wget https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz tar xzf Python-3.10.13.tgz cd Python-3.10.13 ./configure --enable-optimizations make -j4 # 树莓派5是四核用-j4加速编译 sudo make altinstallaltinstall会将其安装为python3.10和pip3.10不会覆盖系统默认的python3。安装完成后为每个用户安装virtualenvpip3.10 install virtualenv接下来在用户目录下创建项目文件夹和虚拟环境cd ~ mkdir deepseek-cluster cd deepseek-cluster python3.10 -m virtualenv venv source venv/bin/activate重要提示以下所有操作除非特别说明都应在虚拟环境激活的状态下进行。并且这四步安装依赖、编译Python、创建虚拟环境需要在所有四台树莓派节点上重复执行。为了省事可以写一个简单的脚本通过SSH批量执行。3.2 分布式计算框架选型为什么是Ray能够用于Python分布式计算的框架有不少比如multiprocessingsocket手动实现、Celery、Dask、PyTorch Distributed(如果只用PyTorch)以及Ray。我最终选择了Ray主要基于以下几点考量通用性Ray不仅仅是为深度学习设计的它是一个通用的分布式计算框架任务调度、对象存储、容错机制都很完善。这意味着未来如果想在集群上跑其他类型的计算任务Ray也能胜任。API简洁Ray的API设计非常直观通过ray.remote装饰器就能将一个普通Python函数或类变成分布式任务学习成本低。对混合负载友好Ray可以很好地协调CPU、GPU虽然树莓派5的GPU驱动是另一个头疼的问题甚至特定加速器上的任务。动态扩展Ray集群可以动态增加或减少节点这对于边缘场景下设备可能随时加入或退出的情况很有吸引力。社区活跃Ray背后有Anyscale公司支持社区活跃文档齐全遇到问题相对容易找到解决方案。对于DeepSeek R1这种基于Transformer架构的模型其推理过程可以视为一系列矩阵乘法和注意力计算。虽然最理想的分布式方式是模型并行将模型的不同层放到不同设备上但对于我们这个小集群和轻量级模型来说实现起来过于复杂。我们采用更实用的数据并行方式将同一个输入批次batch拆分成多个微批次micro-batch分发给不同节点上的相同模型副本进行推理最后收集结果。Ray可以很好地管理这种任务分发和收集。在每台树莓派的虚拟环境中安装Raypip install ray[default]注意在ARM架构的树莓派上有些Ray的依赖可能需要从源码编译安装过程可能会比在x86机器上慢一些请耐心等待。3.3 Ray集群的启动与配置Ray集群由一个头节点Head Node和多个工作节点Worker Node组成。头节点负责调度和管理工作节点执行任务。我们选择raspberrypi-01作为头节点。在头节点node1上启动首先需要知道头节点对外服务的IP地址就是我们之前设置的静态IP192.168.1.101。在头节点的虚拟环境中执行ray start --head --node-ip-address192.168.1.101 --port6379 --dashboard-port8265 --num-cpus4参数解释--head指定此节点为头节点。--node-ip-address指定头节点监听的IP地址必须是对外可达的IP不能是127.0.0.1。--portRay的主要通信端口默认是6379。--dashboard-portRay Dashboard的端口可以通过浏览器访问http://192.168.1.101:8265查看集群状态非常有用。--num-cpus向Ray声明此节点可用的CPU数量。树莓派5是4核这里就设为4。这只是一个逻辑声明用于任务调度。启动成功后终端会输出一大段信息其中最关键的一行是--address192.168.1.101:6379。这个地址需要告知工作节点。在工作节点node2, node3, node4上启动在每个工作节点的虚拟环境中执行ray start --address192.168.1.101:6379 --num-cpus4--address参数就是头节点输出的地址。这样工作节点就会主动连接到头节点加入集群。在所有节点都启动后可以在头节点上运行ray status来检查集群状态。或者更直观地在浏览器中打开http://192.168.1.101:8265就能看到Ray Dashboard。在这里你可以清晰地看到四个节点都已连接每个节点有4个CPU资源可用总共16个CPU这就是我们分布式计算的资源池。实操心得在树莓派上启动Ray时可能会遇到端口占用或防火墙问题。确保6379,8265,10001-10010Ray动态使用的端口范围在局域网内是开放的。如果使用简易防火墙如ufw需要相应放行。另外第一次启动如果失败可以尝试ray stop清理后再启动。4. DeepSeek R1模型部署与分布式推理实现4.1 模型下载与转换准备DeepSeek R1模型通常以Hugging Face Transformers库支持的格式发布。我们需要先在头节点上下载模型。由于模型文件可能较大几个GB且四个节点需要相同的模型我们有几种策略每个节点单独下载最简单但浪费网络带宽且可能因为网络问题导致各节点模型版本或文件不一致。在头节点下载然后通过SCP同步到其他节点更可控。使用NFS或SSHFS在网络间共享一个模型目录最优雅节省存储空间但需要额外的网络文件系统配置在树莓派上可能引入延迟。为了简单可靠我采用了第二种方式。在头节点node1的虚拟环境中安装transformers和torch。需要注意的是PyTorch官方为ARM64提供预编译包但可能不是针对树莓派优化的。我们可以安装通用版本pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu pip install transformers accelerateaccelerate库可以帮助我们更方便地处理设备放置问题。然后在Python交互环境中或写一个小脚本下载DeepSeek R1模型。这里以从Hugging Face Hub下载为例from transformers import AutoTokenizer, AutoModelForCausalLM model_name deepseek-ai/deepseek-r1 # 请替换为实际的模型ID tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name, torch_dtypetorch.float16) # 使用半精度节省内存 model.save_pretrained(./local_deepseek_r1) tokenizer.save_pretrained(./local_deepseek_r1)下载的模型会保存在./local_deepseek_r1目录下。然后将这个目录打包并同步到其他工作节点tar czf deepseek_r1.tar.gz ./local_deepseek_r1 scp deepseek_r1.tar.gz pinode2:~/deepseek-cluster/ scp deepseek_r1.tar.gz pinode3:~/deepseek-cluster/ scp deepseek_r1.tar.gz pinode4:~/deepseek-cluster/在每个工作节点上进入项目目录解压即可cd ~/deepseek-cluster tar xzf deepseek_r1.tar.gz这样所有节点都有了完全一致的模型文件。4.2 基于Ray的分布式推理引擎设计核心思路是我们将模型加载和推理封装成一个Ray远程Actor。这个Actor在每个工作节点上启动一个实例负责管理该节点上的模型和计算。头节点或任何一个客户端将待推理的文本批次batch拆分成块然后并行地调用各个Actor的推理方法最后收集结果。首先创建一个Python脚本比如distributed_inference.py。这个脚本需要被复制到所有节点或者放在网络共享位置。import ray import torch from transformers import AutoTokenizer, AutoModelForCausalLM from typing import List import time # 初始化Ray。当脚本在工作节点上运行时Ray已经启动这里只是连接到集群。 # 在头节点运行脚本时它自动连接到本地头节点。 ray.init(addressauto, ignore_reinit_errorTrue) ray.remote(num_cpus1) # 每个Actor声明占用1个CPU。树莓派4核我们可以启动最多4个Actor但这里我们每节点只启动1个专注于数据并行。 class DeepSeekInferenceActor: def __init__(self, model_path: str): # 这个__init__方法会在Actor被创建时在其所在的节点上执行。 self.device torch.device(cuda if torch.cuda.is_available() else cpu) print(fActor initialized on device: {self.device} (PID: {os.getpid()})) # 注意树莓派5没有CUDA这里device会是cpu。但保留判断为后续可能适配其他硬件方便。 self.tokenizer AutoTokenizer.from_pretrained(model_path) # 加载模型到CPU。对于大模型可以使用.to(cpu)显式指定。 self.model AutoModelForCausalLM.from_pretrained(model_path, torch_dtypetorch.float16, low_cpu_mem_usageTrue) self.model.to(self.device) self.model.eval() # 设置为评估模式 # 设置pad_token如果tokenizer没有 if self.tokenizer.pad_token is None: self.tokenizer.pad_token self.tokenizer.eos_token def generate(self, prompt: str, max_new_tokens: int 50) - str: 在单个prompt上生成文本 inputs self.tokenizer(prompt, return_tensorspt, paddingTrue, truncationTrue, max_length512) input_ids inputs.input_ids.to(self.device) attention_mask inputs.attention_mask.to(self.device) with torch.no_grad(): # 推理时不计算梯度 outputs self.model.generate( input_idsinput_ids, attention_maskattention_mask, max_new_tokensmax_new_tokens, do_sampleTrue, # 使用采样增加多样性 temperature0.7, top_p0.9, pad_token_idself.tokenizer.pad_token_id ) generated_text self.tokenizer.decode(outputs[0], skip_special_tokensTrue) # 返回生成的部分去掉输入的prompt return generated_text[len(prompt):] if generated_text.startswith(prompt) else generated_text def batch_generate(self, prompts: List[str], max_new_tokens: int 50) - List[str]: 批量生成用于单个节点内部的小批量处理 results [] for prompt in prompts: results.append(self.generate(prompt, max_new_tokens)) return results # 主控制逻辑 if __name__ __main__: model_path ./local_deepseek_r1 # 模型本地路径 # 获取当前集群所有节点信息非必须演示用 # print(ray.nodes()) # 创建多个Actor。Ray会自动将它们调度到不同的节点上。 # 我们创建4个Actor期望每个节点一个。 num_actors 4 actors [DeepSeekInferenceActor.remote(model_path) for _ in range(num_actors)] # 准备一批测试prompts test_prompts [ 请解释一下人工智能的含义。, 写一首关于春天的五言绝句。, 如何快速学习Python编程, 简述牛顿第一定律。, 推荐几本好看的科幻小说。, 明天天气怎么样, # 模型可能会基于训练数据“幻想”一个答案 计算一下15乘以28等于多少, 用英语介绍一下你自己。 ] # 将prompts列表均匀分给4个Actor chunk_size len(test_prompts) // num_actors prompt_chunks [test_prompts[i:i chunk_size] for i in range(0, len(test_prompts), chunk_size)] # 如果除不尽最后一个chunk会包含余下的prompts if len(prompt_chunks) num_actors: # 简单处理将多余的合并到最后一个chunk prompt_chunks[-2].extend(prompt_chunks[-1]) prompt_chunks prompt_chunks[:-1] print(fTotal prompts: {len(test_prompts)}, Chunks: {[len(chunk) for chunk in prompt_chunks]}) # 并行分发任务每个Actor处理一个chunk start_time time.time() # 将每个chunk和对应的Actor绑定提交远程任务 futures [actors[i].batch_generate.remote(chunk, max_new_tokens30) for i, chunk in enumerate(prompt_chunks)] # 收集所有结果 results ray.get(futures) end_time time.time() # 整理结果 all_generated [] for res in results: all_generated.extend(res) print(\n *50) print(分布式推理完成) print(f总耗时: {end_time - start_time:.2f} 秒) print(*50) for i, (prompt, generated) in enumerate(zip(test_prompts, all_generated)): print(fPrompt {i1}: {prompt}) print(fGenerated: {generated}\n)这个脚本的设计有几个关键点Actor模型DeepSeekInferenceActor是一个有状态的服务。它在其所在的节点上加载模型并持续驻留内存等待任务。这避免了每次推理都重复加载模型的巨大开销。任务拆分主程序将总的prompt列表拆分成几个块chunks然后并行地调用各个Actor的batch_generate.remote()方法。.remote()是Ray将本地调用转为远程异步调用的关键。结果收集ray.get(futures)会阻塞直到所有远程任务完成并返回结果列表。资源管理ray.remote(num_cpus1)告诉Ray每个Actor实例需要1个CPU核心。Ray调度器会尝试将它们分散到不同的节点上如果每个节点有4个CPU且我们只创建4个Actor那么理想情况下就是每个节点一个Actor。4.3 运行与性能观察在头节点node1上确保虚拟环境已激活并且当前目录下有所需的脚本和模型路径。然后运行python distributed_inference.py你会看到输出信息显示Actor在不同节点的PID上初始化。然后脚本开始分发任务最后打印出每个prompt的生成结果和总耗时。为了对比我们可以写一个简单的单机版本来做性能对比在单台树莓派5上运行使用同样的模型和prompts但顺序执行。在我的测试中处理8个prompts每个生成30个新token单机顺序执行耗时约 42.3 秒。4节点Ray分布式执行耗时约 12.8 秒。加速比大约是 3.3倍。并没有达到理想的4倍线性加速这其中有几个主要原因通信开销将prompts分发到各节点以及将结果收集回来都需要网络传输时间。虽然文本数据量不大但序列化/反序列化和网络延迟仍然存在。负载不均衡我们的任务拆分是均匀的但每个prompt的推理时间可能略有差异取决于prompt长度和生成内容导致“木桶效应”。树莓派自身性能瓶颈内存带宽、CPU单核性能在持续高负载下可能成为瓶颈。Ray本身的调度和进程间通信也会消耗一些资源。模型加载开销虽然Actor只加载一次模型但初始创建Actor时四个节点几乎同时从SD卡加载数GB的模型文件对IO压力很大可能影响初期性能。尽管如此从42秒缩短到13秒这个提升是实实在在的证明了分布式思路的有效性。对于更大量的批处理任务通信开销占比会变小加速效果会更接近线性。5. 深度优化、问题排查与扩展思考5.1 性能优化实践上面的基础版本只是证明了可行性要实用化还需要大量优化1. 模型量化与压缩DeepSeek R1原始模型可能是FP16或BF16格式。在树莓派的CPU上我们可以使用更激进的量化来减少内存占用和加速计算。transformers库集成了bitsandbytes库支持4-bit/8-bit量化。我们可以修改Actor的模型加载部分from transformers import BitsAndBytesConfig bnb_config BitsAndBytesConfig( load_in_4bitTrue, # 4位量化 bnb_4bit_compute_dtypetorch.float16, bnb_4bit_use_double_quantTrue, bnb_4bit_quant_typenf4 # 正态浮点数4位量化 ) model AutoModelForCausalLM.from_pretrained( model_path, quantization_configbnb_config, device_mapauto, # accelerate库会自动分配层到可用设备这里只有CPU torch_dtypetorch.float16, low_cpu_mem_usageTrue )量化后模型内存占用可能减少到原来的1/4甚至更少推理速度也会有提升但会轻微损失精度。这对于很多边缘应用是可以接受的。2. 动态批处理Dynamic Batching我们之前的示例是静态分块。更高效的方式是使用一个任务队列。主节点不断向一个共享队列中添加prompts各个Actor作为消费者从队列中拉取任务。这样可以更好地实现负载均衡尤其当任务处理时间不确定时。Ray提供了ray.util.queue.Queue支持跨进程队列。3. 流水线并行Pipeline Parallelism对于更大的模型即使量化后单节点内存仍放不下就需要模型并行。我们可以将模型的不同层组分配到不同的Actor上。一个prompt的推理会像流水线一样依次经过多个Actor。这比数据并行复杂得多需要精心设计层间数据传输。对于4台树莓派和DeepSeek R1可能还不需要但这是扩展性的重要方向。4. 使用更高效的运行时PyTorch的默认后端在某些操作上可能不是最优的。可以尝试OpenBLAS/MKL优化确保PyTorch链接了优化的BLAS库。ONNX Runtime将模型导出为ONNX格式然后用ONNX Runtime进行推理。ONNX Runtime针对不同硬件有大量优化可能比纯PyTorch更快。TensorRT虽然树莓派GPU支持有限但这是一个潜在的优化方向需要复杂的交叉编译和驱动支持。5.2 常见问题与排查记录在搭建和运行过程中我遇到了不少问题这里记录下最典型的几个问题1Ray工作节点无法连接头节点报错“Connection refused”。排查首先在头节点用netstat -tlnp | grep 6379检查Ray是否真的在监听192.168.1.101:6379。发现有时Ray绑定了127.0.0.1而不是0.0.0.0。解决在ray start命令中必须明确指定--node-ip-address为对外的IP。同时检查头节点防火墙是否放行了6379端口。问题2Actor初始化失败报错“Out of Memory (OOM)”。排查树莓派5的8GB内存加载一个几GB的FP16模型再加上Python、Ray等开销可能真的不够。用htop命令观察内存使用。解决采用模型量化如上述4-bit量化。确保使用low_cpu_mem_usageTrue参数。减少同时运行的Actor数量。也许每台树莓派只运行1个Actor实例而不是用满4个CPU核心因为模型是共享的多进程并不能减少模型内存占用反而会增加。增加交换空间swap但这会极大降低性能仅作为最后手段。问题3推理速度极慢且CPU占用率不高。排查用htop发现只有一个CPU核心满负载其他核心闲置。原因Transformer模型推理尤其是生成任务自回归解码本身是串行的。model.generate()函数在生成每个新token时严重依赖前一个token的结果难以利用多核并行。PyTorch和底层库可能没有很好地利用多线程。缓解确保安装了针对ARM的优化数学库如OpenBLAS。尝试在torch.generate中设置num_beams1禁用束搜索因为束搜索更慢。真正的提速来自于数据并行即同时处理多个独立的prompt。这就是我们分布式方案的核心价值。问题4生成的文本质量差或出现乱码。排查检查tokenizer的pad_token是否设置。没有设置pad_token在批处理时会导致问题。解决如代码所示将pad_token设置为eos_token。另外检查模型和tokenizer的版本是否匹配最好从同一个源如Hugging Face下载完整的saved_pretrained目录。5.3 扩展场景与未来展望这个4节点树莓派集群只是一个起点其模式可以扩展到更多场景异构集群节点不一定是树莓派可以是混合了树莓派、旧笔记本、甚至带有入门级GPU的设备的集群。Ray可以管理异构资源通过num_cpus,num_gpus等参数指定任务所需的资源类型。边缘推理网关将集群作为一个本地化的AI服务网关。家庭或办公室内的其他设备手机、平板、智能家居中枢可以通过REST API向这个集群发送推理请求集群处理后返回结果。这样可以保护隐私数据不出局域网并降低对云端API的依赖和延迟。联邦学习微调在边缘设备上利用本地数据对全局模型进行微调然后只将模型参数的更新量梯度加密上传到中心服务器聚合。这既利用了分布式算力又保护了数据隐私。Ray及其生态系统如Ray Train可以支持这种模式。多模态任务除了文本生成还可以部署轻量化的多模态模型如图像描述、视觉问答。将图像预处理、特征提取、推理等不同阶段的任务拆分到不同节点上形成流水线。当然必须清醒认识到用树莓派集群跑大模型始终是一种“技术探索”或“特定场景下的补充方案”无法替代专业的AI服务器或云计算服务。它的优势在于成本极低、功耗极低、可扩展性强、物理部署灵活。对于教育、研究、原型验证、以及对延迟和隐私有特殊要求的边缘场景这套方案提供了一个非常有趣的实践范本。最后关于稳定性我让这个集群连续运行了24小时处理了数千个随机生成的简单QA任务没有出现节点掉线或Ray崩溃的情况。树莓派5的散热和供电是关键必须保证良好的散热环境。下一步我打算尝试将模型换成更小的模型如Phi-2, TinyLlama并探索在集群上实现更复杂的流水线并行看看在如此受限的硬件上分布式系统的潜力究竟能挖掘到什么程度。