私有化部署DeepSeek等大模型的性能估计

私有化部署?

如果你也在这波DeepSeek R1私有化部署的浪潮里,你的老板可能会让你预估下部署一个XX版本的模型需要什么样的硬件资源,TPS是多少。为此,你也许会上网搜索各种测试,你可能会看到这样的图:

图片

这些测评基本上都是机构或者网友基于自己的机器测出来的值,有没有什么方法能够让我们快速估计出一个值作为整体的考量,即使它没有那么精准?

今天,我会带大家一起梳理一下

  1. 1. 大模型推理的性能指标有哪些

  2. 2. 大模型推理的性能和什么相关

  3. 3. 如何快速通过已有的信息,估计出大模型的理论推理性能极限

1. 大模型推理的性能指标

你可能会听过这些词:TTFT,TPOT,Throughput, Latency,TPS等术语,我们来看他们分别代表什么意思:

  • • TTFT(Time To First Token)
    即首token延迟,指的都是从输入到输出第一个token 的延迟,
    在大模型的推理阶段引用了KV Cache,所以会有两个阶段:Prefilling和Decoding阶段,TTFT指的是大模型对prompt完成了KV 缓存的动作,并生成第一个Token的时间

  • • TPOT(Time Per Output Token),
    在Decoding阶段,平均每个输出 token 的延迟(不含首个Token)

  • • Lantency(延迟)

    • • 理论上即从输入到输出最后一个 token 的时间,原则上的计算公式是:Latency = (TTFT) + (TPOT) * (number of tokens);

  • • TPS(Tokens Per Second)

    • • 一般指单个请求的每秒token数,有时候也是并发请求的总吞吐量,注意上下文即可。 计算方式是 number of tokens / Latency;

  • • Throughput 吞吐量

    • • 如果有并发的时候,多个请求每秒总token数量

2. 大模型性能影响因子

那么哪些因子会影响大模型的性能呢?

它和大模型本身,推理使用的GPU,用了什么框架,prompt的长度,并发量等等都有关系,下面我们具体来看

2.1. 大模型本身

首先我们要看模型的架构是Dense还是MoE。对于Dense架构的,在推理的时候会激活所有参数;对于MoE架构,例如DeepSeek R1,模型本身有671B,但激活的只有37B. 推理速度和激活的参数大小有关;

同时,每一个参数可能会用不同的精度,比如BF16,Int8等等,精度越小推理速度就越快。

图片

2.2 GPU

GPU有很多参数,对大模型推理来说,主要的有三个:显存大小,计算能力,通信速度. 我们依次来看下:

图片

当我们说显卡的显存时,我们一般指的是类似于HBM(高带宽存储器),推理时我们会将整个大模型放到显存中,并存入不断增加的KV Cache和计算中间值

通信能力主要分为三块:卡内通信,节点内卡间通信,跨节点通信。卡内通信,一个典型的例子是在计算的的时候,GPU会将数据从HBM中加载到SRAM中,再在SRAM中进行运算,结果传输回HBM进行存储。

节点内卡间通信和跨节点通信,一般是一张显卡没办法加载整个模型,于是计算的时候需要在卡间进行数据的传输。

图片

计算能力和GPU使用率,同一款显卡精度越高,计算能力就越低。同时因为调度和通信的关系,一般没办法打满一张GPU的全部算力。

GPU利用率:当我们谈GPU利用率的时候,一般指的是GPU计算能力的使用率,由于现在的通信能力升级的速度远远跟不上计算能力升级速度,使得通信变成瓶颈,GPU算力因为通信不给力,数据传输不到,经常处于等待的状态。

图片

2.3. 推理框架

是否用到了Flash Attention,Page Attention等

是否能够充分调度GPU

2.4. 推理方式

prompt长度 和 Batch-size

3. 如何快速估计推理计算量

如果你固定了计算能力,要得到TTFT和Throughput等数据,你需要知道是在Prefilling阶段和Decoding的计算量分别是多少。

一个简单的估计是:

Prefilling_FLOPs = 2 * Batch_size * Prompt_size * Parameters

Decoding_FLOPs_Per_Step = 2 * Batch_size * Parameters

Decoding_FLOPs = 2 * Batch_size * Completion_size * Parameters

然而,如果你想仔细的审查每一步的计算量,我们可以用Qwen2.5-32B为例,分别计算两个阶段的FLOPs

首先我们来看模型的结构,Qwen2.5-32B的模型结构如下:

config = {
  "attention_dropout": 0.0,
"bos_token_id": 151643,
"eos_token_id": 151643,
"hidden_act": "silu",
"hidden_size": 5120,
"initializer_range": 0.02,
"intermediate_size": 27648,
"max_position_embeddings": 131072,
"max_window_layers": 64,
"model_type": "qwen2",
"num_attention_heads": 40,
"num_hidden_layers": 64,
"num_key_value_heads": 8,
"rms_norm_eps": 1e-05,
"rope_theta": 1000000.0,
"sliding_window": 131072,
"torch_dtype": "bfloat16",
"transformers_version": "4.43.1",
"vocab_size": 152064
}

我们可以看到,这个模型有64层,每层有40个attention heads,每个attention head有8个key-value heads,每个head的hidden size是5120,intermediate size是27648,vocab size是152064

我们可以计算出这个模型的参数量是:

def calculate_total_parameters(config):
    # 计算嵌入层参数量
    embedding_params = config['vocab_size'] * config['hidden_size']
    # 计算每层的参数量
    # 前馈网络(FFN)部分
    ffn_params = 3 * (config['hidden_size'] * config['intermediate_size'])  # 三个线性层
    # 多头注意力机制部分 Q, K, V
    attention_params = 2 * config['hidden_size'] * config['hidden_size']*config['num_key_value_heads']/config['num_attention_heads'] + config['hidden_size'] * config['hidden_size']
    # 输出投影部分O
    output_projection_params = config['hidden_size'] * config['hidden_size']  # 输出投影
    # 每层的总参数量
    layer_params = ffn_params + attention_params + output_projection_params
    # 总参数量
    total_params = embedding_params + layer_params * config['num_hidden_layers']
    return total_params/ 1e9
    
    
# 总参数量
total_params = calculate_total_parameters(config)
print(f"总参数量: {total_params:.2f} B")

我们可以得到这个模型的总参数量: 31.98 B

接下来我们可以计算出这个模型的Prefilling_FLOPs和Decoding_FLOPs

config = {
  "attention_dropout": 0.0,
"bos_token_id": 151643,
"eos_token_id": 151643,
"hidden_act": "silu",
"hidden_size": 5120,
"initializer_range": 0.02,
"intermediate_size": 27648,
"max_position_embeddings": 131072,
"max_window_layers": 64,
"model_type": "qwen2",
"num_attention_heads": 40,
"num_hidden_layers": 64,
"num_key_value_heads": 8,
"rms_norm_eps": 1e-05,
"rope_theta": 1000000.0,
"sliding_window": 131072,
"torch_dtype": "bfloat16",
"transformers_version": "4.43.1",
"vocab_size": 152064,
"prompt_token_length": 1024,
"output_token_length": 1024,
"batch_size": 1,
}

defcalculate_prefilling_FLOPs(config):
    ## Q投影计算量
    query_projection_flops = 2*config['prompt_token_length'] * config['hidden_size']**2
    ## K,v投影计算量
    key_projection_flops = 2* config['prompt_token_length'] * config['hidden_size']**2 * config['num_key_value_heads']/config['num_attention_heads'] 
    value_projection_flops = 2* config['prompt_token_length'] * config['hidden_size']**2 * config['num_key_value_heads']/config['num_attention_heads'] 
    ## attention计算量
    # kv 在GQA的状态下,kv的存储量变小,但是计算量不变,因为K和V会有广播
    Q_K_flops = 2* config['prompt_token_length']**2 * config['hidden_size']
    A_V_flops = 2* config['prompt_token_length']**2 * config['hidden_size']
    ## 输出投影计算量
    output_projection_flops = 2*config['prompt_token_length'] * config['hidden_size']**2

    ## 前馈网络计算量
    ## swiGLu 有三次线性变换
    ffn_flops = 3* 2* config['prompt_token_length'] * config['hidden_size'] * config['intermediate_size']

    layer_flops = query_projection_flops + key_projection_flops + value_projection_flops + Q_K_flops + A_V_flops + output_projection_flops + ffn_flops

    total_flops = layer_flops * config['num_hidden_layers']*config['batch_size']
    return total_flops/ 1e12
    
    
calculate_prefilling_FLOPs(config)


defcalculate_prefilling_FLOPs_quick(config):
    total_flops = (4*(1+config['num_key_value_heads']/config['num_attention_heads'])*config['prompt_token_length']*config['hidden_size']**2
                   + 4*config['prompt_token_length']**2*config['hidden_size']
                   + 6*config['prompt_token_length'] *
                   config['hidden_size']*config['intermediate_size'])*config['num_hidden_layers']*config['batch_size']
    return total_flops/ 1e12
    
    
calculate_prefilling_FLOPs_quick(config)


total_prefilling_flops = calculate_prefilling_FLOPs(config)
print(f"Prefilling阶段总计算量: {total_prefilling_flops:.2f} TFLOPs")

Prefilling阶段总计算量: 65.28 TFLOPs

Decoding阶段的计算量

def calculate_decoding_FLOPs_per_token(config):
        ## Q投影计算量
    query_projection_flops = 2* config['hidden_size']**2
    ## K,v投影计算量,每次计算一个token的kv
    key_projection_flops = 2* config['hidden_size']**2 * config['num_key_value_heads']/config['num_attention_heads'] 
    value_projection_flops = 2* config['hidden_size']**2 * config['num_key_value_heads']/config['num_attention_heads'] 
    ## attention计算量
    # kv cache的状态下,KV的大小的随着step的增加而增加,从初始的prompt_token_length 到最终的prompt_token_length+output_token_length
    Q_K_flops = 2* (config['prompt_token_length']+(1+config['output_token_length'])/2) * config['hidden_size']
    A_V_flops = 2* (config['prompt_token_length']+(1+config['output_token_length'])/2) * config['hidden_size']
    ## 输出投影计算量
    output_projection_flops = 2* config['hidden_size']**2

    ## 前馈网络计算量
    ## swiGLu 有三次线性变换
    ffn_flops = 3* 2* config['hidden_size'] * config['intermediate_size']

    layer_flops = query_projection_flops + key_projection_flops + value_projection_flops + Q_K_flops + A_V_flops + output_projection_flops + ffn_flops

    total_flops = layer_flops * config['num_hidden_layers']*config['batch_size']
    return total_flops/ 1e12
    
decoding_FLOPs_per_token = calculate_decoding_FLOPs_per_token(config)
print(f"平均每个token的计算量: {decoding_FLOPs_per_token:.2f} TFLOPs")

平均每个token的计算量: 0.06 TFLOPs

4. 理论性能和GPU利用率

Prefilling

TTFT = Prefilling_FLOPs / GPU_FLOPS

计算得Prefilling阶段总计算量: 65.28 TFLOPs

理论TTFT = 65.28TFLOPs/148TFLOPs = 441ms

但是GPU的使用率一般没办法跑满60%左右,所以延迟会更高些。

Decoding

计算得每一个batch生成的计算量为0.06TFLOPs

理论上的throughput = 148TFLOPS/0.06TFLOPs = 2466token/s

但是由于GPU的利用率,我们可以估计出来的TPS会更低

一个快速估计的方法

Prefilling_FLOPs = 2 * Batch_size * Prompt_size * Parameters= 2 * 1 * 1024 * 32B = 64TFLOPs
估计TTFT = 64TFLOPs/148TFLOPs=432ms

Decoding_FLOPs_Per_Step = 2 * Batch_size * Parameters = 2 * 1 * 32B = 0.064TFLOPs

快速估计的理论Throughput = 148TFLOPS/0.064TFLOPs = 2312token/s

 

 大模型&AI产品经理如何学习

求大家的点赞和收藏,我花2万买的大模型学习资料免费共享给你们,来看看有哪些东西。

1.学习路线图

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。


2.视频教程

网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己整理的大模型视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。

(都打包成一块的了,不能一一展开,总共300多集)

因篇幅有限,仅展示部分资料,需要点击下方图片前往获取

3.技术文档和电子书 

这里主要整理了大模型相关PDF书籍、行业报告、文档,有几百本,都是目前行业最新的。



4.LLM面试题和面经合集


这里主要整理了行业目前最新的大模型面试题和各种大厂offer面经合集。



👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集***

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

<think>嗯,用户问的是如何在群晖NAS上私有化部署DeepSeek大模型。首先,我得确定DeepSeek大模型的具体情况,因为不同的模型可能有不同的部署方式。比如像LLaMA或者Alpaca这样的模型,通常需要特定的框架支持,比如Hugging Face的Transformers或者使用llama.cpp这样的工具。但用户提到的是DeepSeek,可能是一个特定的模型,我需要先确认这个模型的开源情况以及支持的推理框架。 接下来,群晖NAS的硬件配置是关键。大模型通常需要较强的GPU支持,但大多数家用群晖设备可能只有CPU,没有独立显卡。这样的话,部署像7B或13B参数的模型可能会比较吃力,推理速度会很慢。用户可能需要考虑模型量化,比如使用llama.cpp的GGUF格式,或者用Transformers的int8量化来减少内存占用。 然后是软件环境。群晖NAS通常运行的是基于Linux的系统,但可能没有直接的root访问权限,或者需要套件中心来安装软件。比如,用户可能需要通过Docker来部署,因为群晖支持Docker套件。这时候需要准备一个包含CUDA支持的Docker镜像(如果有GPU的话),或者仅使用CPU的基础镜像。 另外,模型文件的获取也是一个问题。用户需要从合法的渠道下载DeepSeek的模型权重,可能需要申请权限或者遵守特定的开源协议。下载后,如何将模型文件放入NAS的存储目录,并确保Docker容器能正确访问到这些路径。 接下来是具体的部署步骤。比如,使用Docker运行一个文本生成的Web界面,比如oobabooga的text-generation-webui,或者使用简化版的llama.cpp的server。需要编写或获取相应的Dockerfile,配置端口映射,挂载卷,设置环境变量等。 可能还需要考虑性能优化,比如调整线程数、批处理大小,或者开启量化来降低资源消耗。同时,安全方面的问题,比如是否需要设置访问权限,防止NAS上的服务被外部访问。 用户可能的实际使用场景是什么?他们可能希望有一个本地化的AI助手,处理文本生成、问答或者其他任务,同时保证数据隐私。所以私有化部署是关键,确保数据不离开本地NAS。 此外,用户的技术水平可能参差不齐,所以步骤需要尽量详细,避免使用太多专业术语,或者提供不同的方法,比如使用Docker还是直接安装Python环境,或者使用现有的群晖套件(如果有的话)。 最后,验证部署是否成功,比如通过curl测试API,或者访问Web界面进行交互。同时提醒用户注意模型的硬件要求,如果NAS性能不足,可能需要升级硬件或选择更小的模型版本。</think>在群晖NAS中私有化部署大模型(如DeepSeek或其他开源模型)需要结合硬件性能、软件环境和具体模型要求。以下是一个通用部署流程,以 **CPU/GPU混合环境** 为例,针对中文场景优化: --- ### **一、准备工作** 1. **确认硬件配置** - **最低要求**:x86架构群晖(DSM 7.0+),4核CPU,8GB内存(仅支持小模型如 1.3B-7B 参数)。 - **推荐配置**:带有NVIDIA显卡的群晖(如部分XS/XS+型号),16GB+内存,SSD缓存加速。 2. **获取模型文件** - 从官方渠道下载DeepSeek模型(如Hugging Face或官方GitHub),确保格式为 `.bin` (GGML) 或 `.safetensors`。 - 若需中文优化,可选择类似`Chinese-LLaMA-Alpaca`等社区优化版本。 --- ### **二、部署方式(推荐Docker)** #### **方法1:使用`text-generation-webui`(可视化界面)** ```bash # 通过群晖Docker套件操作 1. 拉取镜像:选择`oobabooga/text-generation-webui`官方镜像。 2. 配置容器: - 挂载模型目录:`/models` ➔ NAS中的模型文件夹(如`/docker/llm/models`) - 端口映射:7860(Web UI)、5000(API) 3. 环境变量: - `CLI_ARGS=--model deepseek-7b --cpu` (纯CPU模式) - 若有GPU:`CLI_ARGS=--model deepseek-7b --auto-devices` 4. 启动后访问:http://群晖IP:7860 ``` #### **方法2:使用`llama.cpp`(轻量CPU优化)** ```bash 1. 通过SSH登录群晖,安装基础依赖: sudo apt-get update && sudo apt-get install build-essential 2. 编译llama.cpp: git clone https://github.com/ggerganov/llama.cpp cd llama.cpp && make 3. 转换模型为GGUF格式(需提前下载): python3 convert.py --input-model /path/to/deepseek --output-gguf /output/ggml-model-f16.gguf 4. 量化模型(节省内存): ./quantize ggml-model-f16.gguf ggml-model-q4_0.gguf q4_0 5. 启动API服务: ./server -m ggml-model-q4_0.gguf -c 2048 --port 8080 ``` --- ### **三、中文优化技巧** 1. **模型选择** - 优先选择已针对中文优化的模型(如`DeepSeek-Chat`或`ChatGLM3`)。 2. **提示词模板** - 使用中文系统提示词(如“你是一个由DeepSeek开发的中文AI助手”)。 3. **性能调优** - CPU模式:设置`--threads`参数为物理核心数(如4核CPU设为4)。 - GPU加速(仅限支持型号):添加`--n-gpu-layers 20`加载部分层到显卡。 --- ### **四、常见问题** - **内存不足**:尝试量化模型(如Q4_K_M)或使用更小模型(如Phi-3-mini)。 - **速度慢**:启用群晖SSD缓存,或通过API异步调用。 - **无显卡支持**:使用`llama.cpp`或`mlc-llm`等CPU优化框架。 --- ### **五、进阶方案** - **集成至群晖服务**:通过反向代理(Nginx)绑定域名,搭配群晖SSL证书启用HTTPS。 - **结合本地应用**:使用Synology Drive同步模型文件,或通过Webhook对接ChatBot。 部署完成后,可通过`curl http://localhost:5000/api/v1/generate -d '{"prompt":"你好"}'`测试API,或直接在Web界面交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值