基于reSpeaker XVF3800与声网ten-framework构建边缘AI语音对话系统

发布时间:2026/8/2 8:13:46
基于reSpeaker XVF3800与声网ten-framework构建边缘AI语音对话系统 1. 项目概述当硬件麦克风阵列遇上边缘AI语音对话最近在折腾一个挺有意思的项目把reSpeaker XVF3800这块专业的麦克风阵列开发板和声网Agora的ten-framework边缘AI对话框架给搭起来搞一个能跑在本地的、低延迟的智能语音对话客户端。这玩意儿说白了就是想摆脱对云端服务器的绝对依赖让语音交互的“大脑”离“耳朵”更近一点。你想想看无论是智能家居的中控、车载语音助手还是线下商场的互动屏如果每次“唤醒”和“理解”都要把音频数据传到千里之外的云上再等结果传回来那个延迟和网络不确定性就够头疼的了。我们这个组合目标就是把语音唤醒、降噪、回声消除、语音识别ASR和自然语言理解NLU这些核心能力尽可能地“压”到设备端或者近场的边缘服务器上。reSpeaker XVF3800是Seeed Studio推出的一款高性能麦克风阵列板核心是XMOS的XVF3800芯片。这东西可不是普通的麦克风它内置了强大的DSP能实时处理多路麦克风信号实现声源定位、波束成形、噪声抑制这些高级功能相当于给设备装上了一对“智能耳朵”能在嘈杂环境里清晰地抓取你的声音。而声网的ten-framework则是一个专注于边缘侧实时音视频与AI处理的软件框架它提供了从音频采集、前处理、编解码到AI推理的一整套工具链特别是其对话AI能力可以本地化部署语音交互的完整链路。我之所以琢磨这个组合是因为看到越来越多的场景需要“离线可用”或“超低延迟”的语音交互。比如一些对隐私要求极高的会议场景用户不希望语音数据出本地网络又比如工业巡检机器人在车间网络不稳定的环境下依然需要可靠的语音指令控制。把XVF3800的硬件前处理优势和ten-framework的软件AI能力结合正好能应对这些挑战。接下来我就把从硬件准备、软件部署到联调测试的完整过程以及中间踩过的坑和总结的经验详细拆解一遍。2. 核心硬件与软件栈深度解析2.1 reSpeaker XVF3800你的设备如何获得“顺风耳”reSpeaker XVF3800这块板子是整套系统的“感官前端”。它的核心价值在于提供了企业级的音频前端处理能力。板子上集成了6个数字MEMS麦克风以环形阵列排布。为什么是6个这是一个在成本、性能和物理尺寸间比较平衡的选择。少于4个麦克风声源定位和波束成形的效果会大打折扣多于8个虽然理论上效果更好但算法复杂度和硬件成本会急剧上升对于很多嵌入式场景来说并不经济。XVF3800芯片本身是一个双核的xCORE.ai处理器专门为低延迟、高确定性的实时音频处理而设计。它最厉害的地方在于所有关键的音频预处理算法都是固化在芯片内部的硬件逻辑或高度优化的固件中的包括自适应波束成形这就像是给麦克风阵列加上了一个可以自动转向的“手电筒”。它能根据声源的方向实时调整各个麦克风信号的权重和相位形成一个指向说话人的拾音波束从而有效抑制其他方向的噪声和混响。XVF3800支持多达4个独立的波束可以同时追踪多个说话人。噪声抑制不仅仅是简单的滤波。它能区分稳态噪声如空调声、风扇声和非稳态噪声如键盘敲击、短暂碰撞并针对性地进行抑制在消除噪音的同时最大程度地保留人声的清晰度和自然度。声学回声消除这是实现全双工对话的关键。当设备本身也在播放声音比如音箱在回答你时AEC算法能预测并减去从扬声器到麦克风的回声防止系统把自己的输出误认为是用户的输入从而避免“自激振荡”。自动增益控制根据说话人距离的远近自动调整拾音音量保证输入到后续ASR引擎的音频信号幅度稳定在一个最佳范围内。这些处理都是在音频信号进入主应用处理器比如树莓派、Jetson Nano或者x86主机之前完成的。这意味着主CPU拿到的是已经非常“干净”的音频流大大减轻了软件端进行二次处理的压力也降低了整体系统的功耗和延迟。注意XVF3800需要通过I2S接口与主机通信。I2S是一种专门用于传输数字音频的串行总线。在连接时务必确认主机的I2S引脚定义BCLK, LRCLK, DIN, DOUT, MCLK与XVF3800板子匹配。很多部署问题都出在硬件接口配置错误上。2.2 Agora ten-framework在边缘部署一个对话“大脑”如果说XVF3800是感官那么ten-framework就是边缘设备上的“大脑”。声网将其定位为“实时互动边缘计算框架”它不是一个单一的应用而是一个包含多种功能模块的SDK和运行时环境。对于我们这个语音对话客户端项目主要关注它的以下几个核心组件音频设备抽象层它封装了不同操作系统Linux, Windows和不同音频接口ALSA, PulseAudio, CoreAudio的差异提供了一个统一的API来采集和播放音频。这让我们可以相对容易地将XVF3800的I2S音频流接入到框架中。音频前处理流水线虽然XVF3800已经做了大量处理但ten-framework在软件侧仍可进行补充处理例如进一步的非线性噪声抑制、语音活动检测VAD等。框架允许你灵活配置这个处理流水线。AI推理引擎集成这是ten-framework的核心。它内置了或可以对接主流的AI推理运行时如ONNX Runtime、TensorFlow Lite、Pytorch Mobile等。我们的语音识别ASR和自然语言理解NLU模型就是通过这个引擎来加载和执行的。对话管理模块它负责协调整个交互流程监听VAD事件、触发ASR、将文本送入NLU、根据NLU的意图执行本地动作或调用云端API、最后通过TTS合成语音并播放。ten-framework提供了状态机和管理器来简化这个流程的开发。网络与信令可选虽然我们强调边缘处理但ten-framework也保留了与声网云服务或其他自定义后端服务通信的能力用于实现需要联网的功能比如查询天气、播放在线音乐等。ten-framework的一个巨大优势是它的模块化和可裁剪性。你可以只选择部署你需要的组件。例如在资源极其受限的设备上你可以只部署VADASR实现简单的离线语音指令在性能更强的边缘网关则可以部署完整的ASRNLUTTS流水线。2.3 技术选型背后的考量为什么是它们市面上麦克风阵列和语音框架的选择不少为什么偏偏是这对组合这是我基于项目需求和实际踩坑后得出的结论。首先从硬件角度看XVF3800提供了“开箱即用”的成熟音频前端方案。相比使用多个独立麦克风自己编写或集成开源算法如WebRTC的AECSpeex的降噪XVF3800的算法是经过芯片厂商深度优化和验证的性能稳定延迟极低且不消耗主CPU资源。这对于保证语音交互第一环节的可靠性至关重要。自己调校多麦克风算法是个耗时漫长且效果难以保证的“深坑”。其次ten-framework作为一个商业框架其价值在于“整合”与“优化”。它把音频设备管理、编解码、AI推理、对话逻辑等分散的技术点封装成一个连贯、可管理的整体。开发者不需要自己去解决ALSA的配置难题、不同AI模型输入输出的适配问题、音频前后端的同步问题等。而且声网作为实时音视频领域的专家其在音频处理上的积累也体现在框架中比如其对网络抖动缓冲、抗丢包的处理即使在我们这个以本地为主的场景下也能提升系统的鲁棒性。最后是生态和可持续性。Seeed Studio和声网都有比较活跃的开发者社区和持续的更新维护。这意味着遇到问题时有地方寻找资料和帮助也意味着软件框架能跟上AI模型比如从传统的DNN-HMM ASR模型到端到端的Transformer模型和硬件如新的NPU加速器的发展。这对于一个希望长期维护和迭代的项目来说是重要的保障。3. 系统部署环境搭建与配置3.1 硬件连接与基础系统准备部署的第一步是让主机“认识”并驱动起XVF3800这块板子。我以最常用的树莓派4B运行Raspberry Pi OS和一台x86 Ubuntu 20.04 LTS服务器为例说明关键步骤。硬件连接XVF3800可以通过树莓派的40针GPIO接口直接连接主要用到的是I2S相关的引脚。你需要对照树莓派和XVF3800的引脚图进行连接。通常需要连接的有BCLK(位时钟)LRCLK(左右声道时钟)DIN(数据输入从XVF3800到树莓派)DOUT(数据输出从树莓派到XVF3800用于音频播放如果不需要可省略)MCLK(主时钟某些配置下需要)3.3V电源和GND对于x86主机你可能需要一个USB转I2S的音频编解码器如基于CM6206芯片的将XVF3800的I2S信号通过USB接入主机。这时系统会将XVF3800识别为一个普通的USB音频设备。操作系统与驱动对于树莓派需要确保内核已启用I2S驱动。编辑/boot/config.txt文件添加或取消注释以下行dtparami2son dtoverlayhifiberry-dac # 这是一个常用的I2S overlay不一定完全匹配可能需要根据具体板子调整。Seeed Studio通常会提供对应的overlay文件。更推荐的做法是使用Seeed Studio官方提供的配置脚本或overlay文件。完成修改后重启。对于Ubuntu如果通过USB连接系统通常会自动识别为USB Audio设备。使用lsusb和arecord -l命令检查设备是否被识别。关键检查点安装alsa-utils包使用arecord -l和aplay -l列出所有音频设备。你应该能看到类似于card 1: XVF3800 [ReSpeaker XVF3800], device 0: USB Audio [USB Audio]的输出。记下card号和device号例如hw:1,0后续配置会用到。实操心得硬件连接后先用最简单的命令测试麦克风阵列是否工作正常。arecord -D hw:1,0 -f S16_LE -r 16000 -c 2 -d 5 test.wav。这里-c 2表示录制2个通道XVF3800可能会输出多通道包括处理后的波束输出和原始麦克风信号具体通道映射需查阅手册。播放test.wav听听是否有声音噪音是否在可接受范围。这个步骤能快速隔离问题是出在硬件/驱动层还是上层应用。3.2 ten-framework SDK下载与依赖安装ten-framework的获取通常需要从声网官网的开发者平台下载。你需要注册账号可能还需要申请相关权限。下载的SDK包通常包含头文件.h编译好的库文件.so 用于Linux .dll 用于Windows示例代码文档和工具安装系统依赖ten-framework依赖于一些常见的系统库。在Ubuntu/Debian系统上你需要安装sudo apt-get update sudo apt-get install -y build-essential cmake pkg-config sudo apt-get install -y libasound2-dev libpulse-dev # 音频设备支持 sudo apt-get install -y libssl-dev libcurl4-openssl-dev # 网络与安全 sudo apt-get install -y libopencv-dev # 如果涉及视频处理 # 如果需要Python绑定则安装Python开发包 sudo apt-get install -y python3-dev python3-pip处理AI模型依赖这是配置中的重点和难点。ten-framework的AI推理能力需要后端引擎。以ONNX Runtime为例你需要安装对应版本的ONNX Runtime库。根据你的硬件CPU/GPU和ten-framework的要求从ONNX Runtime官网下载预编译库或者从源码编译。通常需要将ONNX Runtime的库路径添加到系统的动态链接库路径中或者在编译ten-framework示例时通过CMake变量指定。准备你的ASR和NLU模型文件。这些模型需要是ten-framework支持的格式通常是ONNX格式。你可能需要将训练好的模型如Wav2Vec2、Whisper的某个版本转换为ONNX格式并确保输入输出张量的维度与ten-framework的代码期望的一致。编译示例程序进入ten-framework SDK的示例目录通常有一个CMakeLists.txt。mkdir build cd build cmake .. -DONNXRUNTIME_DIR/path/to/your/onnxruntime -DAGORA_SDK_DIR/path/to/ten-framework-sdk make -j$(nproc)编译成功后你会得到可执行文件例如demo_audio_ai。此时先不要运行因为还没有配置音频设备和AI模型。3.3 关键配置文件详解ten-framework通常通过JSON或YAML格式的配置文件来定义行为。你需要重点关注两个配置音频设备配置和AI流水线配置。音频设备配置 (audio_config.json):{ capture: { mode: device, // 从设备采集 device_name: hw:1,0, // 对应 arecord -l 看到的设备 sample_rate: 16000, channels: 2, // 根据XVF3800输出配置可能是1单波束或更多 format: S16LE, frames_per_buffer: 480 // 每个缓冲区帧数影响延迟。480对应30ms在16kHz下 }, playback: { mode: device, device_name: hw:1,0, // 如果播放也用同一设备 sample_rate: 16000, channels: 1, format: S16LE }, aec: { enabled: false // 因为XVF3800硬件已做AEC这里可以关闭软件的AEC避免冲突 }, vad: { enabled: true, mode: local, // 使用本地VAD aggressiveness: 2 // 激进程度1-3值越大越容易检测到语音但也可能误触发 } }这里最重要的就是capture.device_name必须正确指向你的XVF3800设备。channels参数需要与XVF3800固件配置的输出通道数一致通常我们只使用它处理后的主波束输出单声道。AI流水线配置 (ai_pipeline_config.json):{ asr: { enabled: true, engine: onnxruntime, model_path: ./models/asr_model.onnx, vocab_path: ./models/vocab.txt, sample_rate: 16000, feature_dim: 80, model_type: wav2vec2_custom // 模型类型需与代码中处理器匹配 }, nlu: { enabled: true, engine: onnxruntime, model_path: ./models/nlu_intent_model.onnx, intent_list: ./config/intents.json // 意图列表文件 }, tts: { enabled: false // 第一步可以先关闭TTS专注语音识别 } }这个配置文件告诉框架去哪里加载AI模型。model_path是关键必须确保路径正确并且模型文件与当前版本的ONNX Runtime兼容。intent_list文件定义了NLU模型能识别的所有意图如“播放音乐”、“查询天气”以及对应的槽位如“歌曲名”、“城市名”。4. 核心功能实现与联调实战4.1 音频采集与硬件DSP参数调优成功编译并配置后运行示例程序例如./demo_audio_ai -c config/。程序会开始从XVF3800采集音频。首先你需要验证音频流是否正确。程序日志中应该能看到成功打开音频设备、开始采集的提示。你可以让程序将采集到的原始音频保存成文件用音频编辑软件如Audacity打开检查波形是否正常是否有持续的刺耳噪声或静音。接下来是调优XVF3800的DSP参数。XVF3800的固件通常可以通过UART或USB发送AT指令进行配置。Seeed Studio会提供配置工具或文档。关键的调优点包括波束成形方向默认可能是0度正前方。你可以根据设备安装方向调整波束的指向角度。例如如果设备挂在墙上用户从下方说话可能需要将波束下倾30度。AEC参考信号确保XVF3800能正确接收到设备扬声器播放的音频信号作为回声参考。这通常需要正确连接I2S的DOUT线并在固件中启用AEC并配置参考信号通道。噪声抑制强度在非常嘈杂的环境如马路旁可以调高在安静环境可以调低以避免过度抑制导致人声音质受损。增益调整AGC的目标电平确保输出音频的幅度适中既不会饱和削波也不会太小。调优是一个迭代过程。我的方法是在目标环境中录制几段典型的音频近场清晰指令、远场指令、有背景噪声的指令然后通过调整参数重放录制对比处理前后的音频质量。主观听感上追求声音清晰、自然背景噪声和回声被有效抑制。4.2 语音活动检测与唤醒词集成VAD是决定系统何时开始录音并送去做ASR的“开关”。ten-framework内置的VAD通常效果不错。在配置中调整vad.aggressiveness参数如果发现经常漏掉用户说话的头部几个字“你好小X”只识别到“小X”说明VAD不够灵敏需要提高激进程度调低数值例如从2调到1。如果发现经常被环境噪声如咳嗽、关门声误触发说明VAD太敏感需要降低激进程度调高数值例如从2调到3。对于更自然的交互通常需要集成一个唤醒词引擎如Snowboy、Porcupine或自定义的模型。ten-framework可能支持以插件形式集成。其工作流程是音频流持续经过唤醒词检测模块。当检测到预设的唤醒词如“小爱同学”时触发一个事件。该事件激活VAD和ASR模块开始进行后续的指令识别。在一段时间无语音后系统再次回到低功耗的唤醒词监听状态。你需要将唤醒词模型文件通常是.pmdl或.ppn格式放到指定目录并在配置文件中指定路径和灵敏度。4.3 端侧ASR与NLU模型部署与优化这是整个项目的AI核心。部署自有的ASR和NLU模型是摆脱对云端API依赖的关键。ASR模型选择与转换对于边缘设备模型需要在精度、速度和大小之间权衡。轻量级模型如Jasper、QuartzNet、Wav2Vec 2.0的“base”甚至“tiny”版本。这些模型参数量在千万到亿级在树莓派4B上推理时间可能在几百毫秒到一秒左右对于简单指令识别可以接受。模型转换将训练好的PyTorch或TensorFlow模型导出为ONNX格式。使用torch.onnx.export或tf2onnx工具。导出时务必注意指定正确的输入输出名称和动态维度例如输入音频长度可变。在目标设备树莓派上使用相同版本的ONNX Runtime进行验证确保导出无误。NLU模型部署边缘NLU通常处理有限的领域封闭域例如智能家居控制。你可以使用以下方法意图分类槽位填充这是一个经典的流水线。使用一个小的BERT或FastText模型进行意图分类再配合CRF或规则进行槽位提取。将整个流水线分词、特征提取、分类、填充封装成一个ONNX模型或组合模型。端到端模型如使用序列到序列Seq2Seq模型直接输入ASR文本输出结构化JSON。这对模型设计和数据要求较高。将转换好的ASR和NLU模型文件.onnx和对应的词汇表、意图列表文件放置到配置文件指定的model_path目录下。性能优化技巧量化使用ONNX Runtime的量化工具将FP32模型转换为INT8模型。这能显著减少模型体积和提升推理速度通常精度损失很小。这是边缘部署的必备步骤。图优化在加载模型时启用ONNX Runtime的图优化选项如算子融合、常量折叠等。批处理虽然实时音频是流式的但可以将一小段时间如300ms的音频帧缓存起来组成一个小批次batch1进行推理比逐帧推理更高效。硬件加速如果设备带有NPU如树莓派AI Kit的Hailo-8L可以尝试将ONNX模型编译到对应的后端获得巨大的性能提升。这需要ten-framework支持该NPU的推理引擎。4.4 对话逻辑与本地技能开发当ASR和NLU都工作正常后你就得到了结构化的用户指令例如{“intent”: “play_music”, “slots”: {“song_name”: “晴天”}}。接下来就是实现对话逻辑。ten-framework的对话管理模块会提供一个回调函数或事件接口。你需要在这里编写业务逻辑// 伪代码示例 void on_nlu_result(const NLUResult result) { if (result.intent play_music) { std::string song result.slots[song_name]; if (local_music_library.has(song)) { play_local_music(song); tts_speak(正在为你播放 song); } else { tts_speak(抱歉本地没有找到歌曲 song); } } else if (result.intent query_weather) { // 这是一个需要联网的技能 std::string city result.slots[city_name]; std::string weather fetch_weather_from_cloud(city); // 调用网络API tts_speak(city 的天气是 weather); } else if (result.intent control_light) { // 通过本地协议如MQTT、蓝牙控制智能灯 std::string room result.slots[room]; std::string action result.slots[action]; send_mqtt_command(home/light/ room, action); tts_speak(已 action room 的灯); } }你可以根据需求开发各种本地技能设备控制、本地信息查询、定时器等和需要网络辅助的技能。关键在于核心的语音交互链路拾音、唤醒、识别、理解完全在边缘完成只有那些必须联网的服务才需要外部请求。5. 故障排查与性能调优实录5.1 常见部署问题与解决方案在部署过程中我遇到了不少典型问题这里列出一个速查表问题现象可能原因排查步骤与解决方案程序启动失败报错“打开音频设备失败”1. 设备名错误。2. 设备被其他进程占用。3. 权限不足。1. 用arecord -l确认设备名检查配置文件。2. 用fuser -v /dev/snd/*查看哪个进程占用了声卡结束冲突进程。3. 将当前用户加入audio组sudo usermod -a -G audio $USER并重新登录。能录音但全是噪音/无声1. 硬件连接错误特别是时钟线。2. XVF3800固件未正确加载或配置。3. 采样率或格式不匹配。1. 检查I2S线序确保MCLK/BCLK/LRCLK连接正确且稳定。2. 尝试用官方工具重新烧录或配置XVF3800固件。3. 用arecord指定参数录制测试确保与XVF3800输出格式通常为16kHz, S16_LE一致。VAD不触发或频繁误触发1. 音频信号质量差太轻或噪声大。2. VAD灵敏度参数不合适。3. 能量阈值设置不当。1. 先优化XVF3800的AGC和降噪参数确保输入音频干净、幅度适中。2. 调整配置文件中的aggressiveness参数反复测试。3. 有些VAD实现允许设置能量阈值可尝试微调。ASR识别率极低1. 音频前端处理不佳送入ASR的音频不干净。2. ASR模型与音频格式不匹配采样率、声道数。3. 模型本身不适合该场景或未量化。1. 保存ASR模块的输入音频用耳朵听或用工具分析确保它是清晰的人声。2. 确认模型训练时的音频特征如MFCC的提取参数与ten-framework中的预处理一致。3. 尝试在PC上使用相同的模型和音频测试排除模型问题。考虑使用领域数据微调模型或更换更合适的模型。推理延迟过高1秒1. 模型太大或未量化。2. 使用CPU推理且负载过高。3. 音频帧缓冲设置过长。1.必须进行INT8量化。这是降低延迟最有效的方法。2. 使用top命令查看CPU使用率关闭不必要的进程。考虑使用性能更强的硬件。3. 适当减少frames_per_buffer但太小会增加系统调用开销需平衡。唤醒词检测延迟大1. 唤醒词模型计算复杂。2. 检测步长每次推进的音频长度设置过大。1. 选择更轻量的唤醒词模型。2. 在唤醒词检测阶段可以使用比ASR更低的音频分辨率如8kHz来减少计算量。5.2 系统延迟分析与优化边缘对话的核心优势是低延迟。我们需要系统地分析并优化整个链路的延迟。链路分解音频采集与硬件处理延迟XVF3800内部的DSP处理通常是固定且很低的在几毫秒到十几毫秒。软件缓冲与传输延迟从驱动层到用户空间应用音频数据会经过缓冲区。frames_per_buffer参数直接决定了这部分延迟。例如480帧16kHz 30ms。这是必要的缓冲太小会导致CPU频繁中断太大则增加延迟。VAD/唤醒词检测延迟需要累积一小段音频才能做出判断通常为50-200ms。ASR推理延迟这是最大的变量从100ms到几秒不等取决于模型和硬件。NLU推理延迟通常比ASR快一个数量级在10-50ms左右。技能执行与TTS延迟本地技能几乎无延迟TTS合成如果需要联网则延迟不定。优化策略流水线化不要等ASR完全结束再开始NLU。可以采用流式ASR识别出一部分文本后就开始NLU的预判或部分处理。投机执行对于高概率的意图如“打开”后面很大概率是“灯”可以提前准备执行资源。模型蒸馏与量化这是降低ASR延迟的根本。探索更小的模型架构如Squeezeformer等。硬件加速为Jetson Nano、树莓派AI Kit等设备编译启用GPU或NPU加速的ONNX Runtime版本。5.3 资源占用与稳定性保障在资源受限的边缘设备上长期运行稳定性至关重要。内存监控使用htop或编写监控脚本观察程序运行一段时间后内存是否持续增长内存泄漏。ten-framework的示例程序通常比较稳定但自定义的对话逻辑部分需要注意。CPU占用率理想的CPU占用率应在空闲时较低主要等唤醒活动时ASR推理出现峰值但可快速回落。如果持续居高不下需要检查是否有死循环或低效代码。音频线程优先级在Linux下可以通过pthread_setschedparam设置音频采集和播放线程为较高的实时优先级如SCHED_FIFO防止被其他系统任务打断导致音频卡顿或丢失。看门狗机制为整个对话客户端进程设计一个简单的看门狗。可以用一个脚本定时检查进程是否存在或者进程内部用一个独立线程监控主循环是否卡死并在异常时重启进程。日志与诊断实现分级的日志系统INFO, WARN, ERROR。将关键的运行状态、错误信息、性能指标如每帧处理时间记录到文件或系统日志中便于后期问题追溯。部署这样一个边缘对话客户端是一个涉及硬件、驱动、音频处理、AI模型和软件工程的综合项目。从选型、搭建、调优到稳定运行每一步都需要仔细验证和耐心调试。但一旦跑通你将获得一个响应迅速、隐私安全、不依赖网络的智能语音交互能力这对于构建真正自主的嵌入式智能设备来说价值巨大。我的体会是最难的不是单一模块的使用而是让整个链条协同工作并在真实的、多变的环境中保持稳定可靠。这需要大量的测试从安静的实验室到嘈杂的现场不断收集数据、调整参数、优化模型。