南北阁 Nanbeige 4.1-3B 部署案例国产麒麟V10系统海光CPU平台适配记录1. 项目背景与挑战最近在国产化平台上部署AI模型的需求越来越多了。我手头正好有一个任务要在搭载海光CPU和国产麒麟V10操作系统的服务器上部署南北阁的Nanbeige 4.1-3B模型。这个场景挺有代表性的——很多单位都在推进信创改造但AI模型的部署往往卡在环境适配这一关。海光CPU虽然性能不错但生态和常见的x86平台还是有些差异麒麟V10作为国产操作系统软件包的版本管理也比较特殊。我拿到的这个Nanbeige 4.1-3B模型是一个30亿参数的中文对话模型。参数规模适中理论上对硬件要求不高但要在国产平台上跑起来还得解决几个实际问题第一是环境依赖。PyTorch、Transformers这些框架对CPU架构和操作系统版本都有要求得找到兼容的版本组合。第二是性能优化。纯CPU推理本来就比GPU慢如果软件栈没调好响应速度可能让人无法接受。第三是易用性。部署完了还得有个好用的界面让非技术人员也能方便地测试和体验。下面我就把整个适配过程记录下来包括踩过的坑和最终的解决方案。如果你也在做类似的国产平台AI部署这些经验应该能帮上忙。2. 环境准备与系统检查2.1 硬件与操作系统确认首先得搞清楚我们面对的是什么环境。这台服务器的配置是这样的CPU海光Hygon C86 处理器8核16线程内存32GB DDR4存储512GB NVMe SSD操作系统银河麒麟V10 SP1基于Linux内核用几个简单的命令就能确认系统信息# 查看CPU信息 cat /proc/cpuinfo | grep model name | head -1 # 查看操作系统版本 cat /etc/os-release # 查看内核版本 uname -r输出显示确实是海光CPU和麒麟系统。这里有个细节要注意麒麟V10默认的Python版本可能是3.7或3.8而我们要用的AI框架通常需要Python 3.8以上。2.2 Python环境搭建麒麟系统的软件源里Python版本可能比较旧我建议用Miniconda来管理Python环境这样更灵活。# 下载Miniconda安装包选择Linux版本 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh # 安装 bash Miniconda3-latest-Linux-x86_64.sh # 创建专门的Python环境 conda create -n nanbeige python3.9 conda activate nanbeige用Conda的好处是能解决很多依赖问题特别是那些需要编译的C扩展库。3. 关键依赖安装与适配3.1 PyTorch的兼容性选择这是最关键的步骤。PyTorch官方通常只提供x86架构的预编译包海光CPU需要找兼容的版本。经过测试我发现以下组合比较稳定# 安装兼容的PyTorch版本 pip install torch1.13.1 torchvision0.14.1 torchaudio0.13.1 # 验证安装 python -c import torch; print(fPyTorch版本: {torch.__version__}) python -c import torch; print(fCPU信息: {torch.__cpu__})如果直接安装失败可以尝试从源码编译但那样比较耗时。我找到的1.13.1版本在海光CPU上运行良好而且这个版本也支持我们需要的Transformers功能。3.2 Transformers与其他AI库接下来安装模型推理相关的库# 安装Hugging Face相关库 pip install transformers4.35.0 pip install accelerate0.24.0 # 安装流式输出需要的库 pip install streamlit1.28.0 # 其他工具库 pip install sentencepiece protobuf这里有个注意事项Transformers的版本要和PyTorch匹配。4.35.0版本对1.13.1的PyTorch支持比较好而且包含了Nanbeige模型需要的配置。3.3 模型下载与准备Nanbeige 4.1-3B模型可以从Hugging Face下载。如果网络条件不好可以先用其他机器下载好再传过来。from transformers import AutoModelForCausalLM, AutoTokenizer # 指定模型路径可以是本地路径或Hugging Face模型ID model_name nanbeige/nanbeige-4.1-3b # 下载模型和分词器 print(正在下载模型这可能需要一些时间...) model AutoModelForCausalLM.from_pretrained( model_name, trust_remote_codeTrue, torch_dtypetorch.float16 # 使用半精度减少内存占用 ) tokenizer AutoTokenizer.from_pretrained( model_name, trust_remote_codeTrue, use_fastFalse # 重要必须关闭fast tokenizer ) print(模型下载完成)如果下载速度慢可以考虑用镜像源或者找国内的模型托管平台。4. 模型加载参数精准配置4.1 关键参数说明Nanbeige模型有几个特殊的加载参数必须严格按照官方要求设置否则可能无法正常生成文本。import torch from transformers import AutoModelForCausalLM, AutoTokenizer def load_nanbeige_model(model_path): 加载Nanbeige 4.1-3B模型 # 关键参数1必须设置use_fastFalse tokenizer AutoTokenizer.from_pretrained( model_path, trust_remote_codeTrue, use_fastFalse # 禁用fast tokenizer ) # 关键参数2设置正确的eos_token_id # Nanbeige模型的结束符ID是166101 if tokenizer.eos_token_id is None: tokenizer.eos_token_id 166101 # 加载模型使用半精度减少内存占用 model AutoModelForCausalLM.from_pretrained( model_path, trust_remote_codeTrue, torch_dtypetorch.float16, device_mapauto if torch.cuda.is_available() else cpu ) # 设置为评估模式 model.eval() return model, tokenizer这里有两个关键点use_fastFalseNanbeige的分词器实现需要关闭fast模式eos_token_id166101必须正确设置结束符否则生成不会停止4.2 内存优化策略在CPU上运行30亿参数的模型内存管理很重要。我采用了几个优化策略# 策略1使用半精度模型 model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, # 半精度内存减半 low_cpu_mem_usageTrue # 减少CPU内存占用 ) # 策略2启用CPU内存映射如果内存紧张 model AutoModelForCausalLM.from_pretrained( model_path, torch_dtypetorch.float16, device_mapcpu, offload_folderoffload # 临时文件目录 ) # 策略3限制最大生成长度 generation_config { max_new_tokens: 512, # 限制生成长度 do_sample: True, temperature: 0.6, top_p: 0.95, repetition_penalty: 1.1 }经过这些优化模型在32GB内存的服务器上运行稳定推理时内存占用控制在10GB左右。5. 流式对话工具实现5.1 核心推理函数流式输出的核心是使用TextIteratorStreamer它能实现逐字输出的效果。from transformers import TextIteratorStreamer from threading import Thread import time def generate_stream_response(model, tokenizer, prompt, generation_config): 生成流式响应 # 编码输入 inputs tokenizer(prompt, return_tensorspt) # 创建流式处理器 streamer TextIteratorStreamer( tokenizer, skip_promptTrue, # 跳过提示内容 timeout60.0 # 超时时间 ) # 在单独线程中运行生成过程 generation_kwargs dict( **inputs, streamerstreamer, **generation_config ) thread Thread(targetmodel.generate, kwargsgeneration_kwargs) thread.start() # 逐字输出结果 generated_text for new_text in streamer: generated_text new_text yield new_text # 每次生成一个字或词就返回 return generated_text5.2 CoT思考过程处理Nanbeige模型支持思维链Chain-of-Thought推理输出中会包含think标签包裹的思考过程。我们需要把这些内容提取出来用更好的方式展示。import re def parse_cot_response(full_response): 解析包含CoT思考过程的响应 返回思考过程、最终回答 # 匹配think标签内容 think_pattern rthink(.*?)/think think_matches re.findall(think_pattern, full_response, re.DOTALL) if think_matches: # 提取思考过程 think_content think_matches[0].strip() # 移除思考过程得到最终回答 final_answer re.sub(think_pattern, , full_response, flagsre.DOTALL).strip() return think_content, final_answer else: # 没有思考过程的情况 return None, full_response.strip()5.3 Streamlit界面设计Streamlit让我们能快速搭建一个美观的Web界面。我设计了一个简洁的聊天界面import streamlit as st import time def main(): st.set_page_config( page_titleNanbeige 4.1-3B 对话助手, page_icon, layoutwide ) # 自定义CSS样式 st.markdown( style .chat-message { padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .user-message { background-color: #e3f2fd; border-left: 4px solid #2196f3; } .assistant-message { background-color: #f5f5f5; border-left: 4px solid #4caf50; } .thinking { color: #666; font-style: italic; } /style , unsafe_allow_htmlTrue) # 初始化会话状态 if messages not in st.session_state: st.session_state.messages [] # 侧边栏 with st.sidebar: st.title(设置) # 生成参数调整 temperature st.slider(温度, 0.1, 1.0, 0.6, 0.1) max_tokens st.slider(最大生成长度, 128, 1024, 512, 128) # 清空历史按钮 if st.button(清空对话历史): st.session_state.messages [] st.rerun() # 主界面 st.title(南北阁 Nanbeige 4.1-3B) st.caption(国产30亿参数对话模型 - 纯本地运行) # 显示历史消息 for message in st.session_state.messages: with st.chat_message(message[role]): st.markdown(message[content]) # 输入框 if prompt : st.chat_input(请输入您的问题...): # 添加用户消息 st.session_state.messages.append({role: user, content: prompt}) with st.chat_message(user): st.markdown(prompt) # 生成助手回复 with st.chat_message(assistant): message_placeholder st.empty() full_response # 显示思考中状态 thinking_placeholder st.empty() thinking_placeholder.markdown(*( 思考中...)*) # 模拟流式输出 for chunk in generate_response(prompt): full_response chunk message_placeholder.markdown(full_response ▌) time.sleep(0.02) # 控制输出速度 # 移除光标 message_placeholder.markdown(full_response) # 解析CoT思考过程 think_content, final_answer parse_cot_response(full_response) if think_content: # 隐藏思考过程显示最终答案 thinking_placeholder.empty() with st.expander( 展开查看模型的思考过程): st.markdown(f\n{think_content}\n) st.markdown(final_answer) else: thinking_placeholder.empty() st.markdown(full_response) # 保存助手回复 st.session_state.messages.append({role: assistant, content: full_response})6. 部署与优化实践6.1 启动脚本编写为了方便部署我编写了一个启动脚本自动处理环境检查和模型加载#!/bin/bash # start_nanbeige.sh echo 启动 Nanbeige 4.1-3B 对话系统 # 检查Python环境 if ! command -v python3 /dev/null; then echo 错误未找到Python3请先安装Python3.8或更高版本 exit 1 fi # 检查依赖 echo 检查Python包依赖... pip list | grep -E torch|transformers|streamlit || { echo 正在安装依赖... pip install torch transformers streamlit } # 检查模型文件 MODEL_DIR./models/nanbeige-4.1-3b if [ ! -d $MODEL_DIR ]; then echo 模型目录不存在请先下载模型 echo 运行: python download_model.py exit 1 fi # 启动Streamlit应用 echo 启动Web界面... streamlit run app.py --server.port 8501 --server.address 0.0.0.0 echo 启动完成请在浏览器中访问 http://localhost:85016.2 性能调优建议在海光CPU上运行我总结了几条性能优化经验批处理推理如果有多条输入尽量批量处理缓存机制对常见问题可以缓存回答减少重复计算响应压缩对长文本响应进行智能截断或总结异步处理使用异步IO避免阻塞import asyncio from functools import lru_cache # 使用缓存避免重复计算 lru_cache(maxsize100) def get_cached_response(prompt: str) - str: 缓存常见问题的回答 # 这里可以添加一些常见问题的预设回答 common_answers { 你好: 你好我是基于南北阁Nanbeige 4.1-3B模型训练的AI助手。, 你是谁: 我是运行在海光CPU和麒麟系统上的AI对话助手。, } return common_answers.get(prompt, None) async def async_generate_response(prompt: str): 异步生成响应 # 先检查缓存 cached get_cached_response(prompt) if cached: return cached # 异步调用模型 loop asyncio.get_event_loop() response await loop.run_in_executor( None, lambda: generate_response(prompt) ) return response6.3 监控与日志在生产环境部署时监控和日志很重要import logging import psutil import time class PerformanceMonitor: 性能监控器 def __init__(self): self.start_time None self.memory_usage [] def start(self): 开始监控 self.start_time time.time() self.memory_usage [] def record_memory(self): 记录内存使用 process psutil.Process() mem_info process.memory_info() self.memory_usage.append(mem_info.rss / 1024 / 1024) # MB def get_summary(self): 获取性能摘要 if not self.start_time: return {} elapsed time.time() - self.start_time avg_memory sum(self.memory_usage) / len(self.memory_usage) if self.memory_usage else 0 return { total_time: f{elapsed:.2f}秒, avg_memory: f{avg_memory:.1f}MB, max_memory: f{max(self.memory_usage):.1f}MB if self.memory_usage else 0MB } # 配置日志 logging.basicConfig( levellogging.INFO, format%(asctime)s - %(name)s - %(levelname)s - %(message)s, handlers[ logging.FileHandler(nanbeige_deployment.log), logging.StreamHandler() ] ) logger logging.getLogger(__name__)7. 实际效果与总结7.1 部署效果展示经过上述步骤我在海光CPU麒麟V10的平台上成功部署了Nanbeige 4.1-3B模型。实际运行效果如下响应速度在8核海光CPU上生成512个token的平均时间约为15-20秒。虽然比不上GPU但对于对话场景来说可以接受。内存占用模型加载后常驻内存约8GB推理时峰值内存约12GB在32GB内存的服务器上运行流畅。对话质量30亿参数的模型在中文对话上表现不错能理解上下文回答也比较连贯。思维链功能让推理过程更透明。界面体验Streamlit提供的Web界面简洁美观流式输出效果流畅思考过程的折叠展示让界面更清晰。7.2 遇到的问题与解决方案在整个适配过程中我遇到了几个典型问题PyTorch版本兼容性最初尝试了PyTorch 2.0版本但在海光CPU上编译扩展时失败。降级到1.13.1后解决。内存不足第一次加载模型时遇到了OOM错误。通过使用torch.float16半精度和low_cpu_mem_usageTrue参数解决。分词器错误直接使用默认的fast tokenizer会导致生成异常。必须设置use_fastFalse。生成不停止没有正确设置eos_token_id导致生成一直继续。设置为166101后正常。7.3 经验总结这次国产平台AI模型部署实践让我有几个深刻体会第一版本兼容性是关键。国产平台的软件生态还在完善中选择经过验证的版本组合能避免很多问题。PyTorch 1.13 Transformers 4.35 Python 3.9这个组合在海光麒麟环境下比较稳定。第二内存优化很重要。CPU推理对内存敏感一定要用半精度、内存映射这些技术。32GB内存是底线如果可能的话建议64GB。第三用户体验不能忽视。即使后端是CPU推理通过流式输出和好的界面设计用户感知的响应速度会快很多。第四监控和日志要提前规划。特别是生产环境部署没有监控就像盲人摸象出了问题很难排查。7.4 后续优化方向虽然现在已经能跑了但还有优化空间量化压缩尝试4bit或8bit量化进一步降低内存占用和提升速度。模型蒸馏用更大的模型蒸馏一个小版本在保持效果的同时减少参数。硬件加速研究海光CPU的特定指令集优化比如是否支持AVX512等。边缘部署尝试在更低端的国产硬件上运行比如飞腾或龙芯平台。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。