SUNFLOWER MATCH LAB 自动化测试编写Python脚本进行模型批量识别与结果验证最近在跟进一个图像识别项目模型部署上线后最让人头疼的就是怎么知道它一直“健康”呢总不能天天手动上传图片去测吧。今天就来聊聊我们是怎么用Python写了个自动化测试脚本像给模型做“定期体检”一样确保SUNFLOWER MATCH LAB服务在生产环境里稳定可靠。简单说这个脚本的核心任务就是定时、自动地拿一批我们事先知道答案的图片去“考”模型然后自动批改试卷算出分数准确率最后生成一份体检报告。一旦发现模型“成绩”下滑立马发警报让我们能第一时间介入处理。这套方法特别适合那些已经上线、需要持续监控的模型服务能有效避免因为数据漂移或服务异常导致的线上问题。1. 为什么需要自动化测试模型部署上线只是万里长征第一步。线上环境复杂多变今天表现好好的模型明天可能因为各种原因“状态不佳”。比如新来的数据分布和训练时不一样了或者服务器资源波动影响了推理速度甚至代码更新引入了意想不到的Bug。手动测试效率低、不及时还容易出错。我们需要的是一套能7x24小时工作的“哨兵”系统。自动化测试脚本就是这个哨兵它能定期、客观地评估模型状态把我们从重复的体力劳动中解放出来更专注于分析问题和优化模型。2. 设计我们的自动化测试方案在动手写代码之前我们先得把整个流程想清楚。一个好的自动化测试方案应该包含下面几个关键部分。2.1 核心流程梳理整个测试过程可以概括为“准备-执行-验证-报告”四步曲准备阶段准备好一批测试图片并且每张图片都要有正确的标签也就是我们期望模型识别出的结果。这些图片最好能覆盖模型要识别的所有类别并且包含一些容易出错的边缘案例。执行阶段编写脚本自动将这些测试图片一张张或者一批批地发送给SUNFLOWER MATCH LAB的识别接口。验证阶段脚本接收模型返回的识别结果然后和我们事先准备好的正确标签进行比对判断每个识别是对是错。报告与告警阶段统计总的识别准确率生成一份清晰易懂的测试报告比如HTML或Markdown格式。更重要的是设定一个准确率阈值比如95%一旦低于这个阈值就自动触发告警通过邮件、钉钉、企业微信等方式通知相关人员。2.2 测试数据准备测试数据是评估的基石。我们专门维护了一个测试图片集。这个数据集有几点讲究代表性要包含模型所有需要识别的类别。比如SUNFLOWER MATCH LAB是用来识别不同品种向日葵的那么测试集里就应该有所有目标品种的图片。多样性同一品种的图片要有不同角度、不同光照、不同背景的模拟真实场景。挑战性可以故意放一些模糊的、有遮挡的、或者类别间比较相似的图片看看模型的“抗压能力”如何。标签准确每一张图片的标签都必须人工核对确保100%正确这是评判模型对错的“标准答案”。我们把这些图片和对应的标签文件比如一个CSV文件或JSON文件放在一个固定的目录里方便脚本读取。2.3 技术工具选型实现这个方案我们主要用到Python的几个常用库它们就像我们工具箱里的得力助手requests负责和SUNFLOWER MATCH LAB的HTTP API进行通信发送图片接收识别结果。PIL(Pillow) 或opencv-python用来在发送前对图片进行一些必要的预处理比如调整大小、转换格式或者只是简单地打开图片。pandas如果测试用例很多用这个库来管理测试用例的标签和最终的比对结果非常方便读写CSV文件、做数据统计都很简单。smtplibemail(Python内置)用于实现邮件告警功能。json用于解析模型返回的JSON格式的结果。schedule或crontab实现定时任务。schedule库适合在脚本内部实现简单的定时循环而Linux系统的crontab则更常用于部署生产环境的定时任务。3. 分步编写Python测试脚本接下来我们一步步把想法变成代码。我会把关键代码贴出来并加上详细注释。3.1 第一步配置与准备首先我们把一些固定的信息配置好比如模型服务的地址、测试数据的位置等。import os import json import pandas as pd from PIL import Image import requests from datetime import datetime # 配置区域 # 1. 模型服务API地址 MODEL_API_URL http://your-sunflower-match-lab-server:port/predict # 请替换为实际地址 # 2. 测试数据集路径 TEST_IMAGES_DIR ./test_dataset/images # 存放测试图片的文件夹 TEST_LABELS_FILE ./test_dataset/labels.csv # 存放图片名和对应正确标签的CSV文件 # 3. 报告输出路径 REPORT_DIR ./test_reports # 4. 告警阈值 (准确率低于此值则触发告警) ACCURACY_ALERT_THRESHOLD 0.95 # 95% # 5. 邮件告警配置 (如果需要) ENABLE_EMAIL_ALERT False SMTP_SERVER smtp.your-email.com SMTP_PORT 587 SENDER_EMAIL your-alertemail.com SENDER_PASSWORD your-password RECEIVER_EMAILS [team-member1email.com, team-member2email.com] # 确保报告目录存在 os.makedirs(REPORT_DIR, exist_okTrue)3.2 第二步加载测试用例我们假设标签文件是一个CSV里面有两列image_name图片文件名和true_label正确标签。def load_test_cases(label_file_path): 加载测试用例图片名和真实标签 try: df pd.read_csv(label_file_path) # 假设CSV文件包含 image_name 和 true_label 列 test_cases list(zip(df[image_name], df[true_label])) print(f成功加载 {len(test_cases)} 个测试用例。) return test_cases except FileNotFoundError: print(f错误未找到标签文件 {label_file_path}) return [] except Exception as e: print(f加载标签文件时发生错误{e}) return [] # 加载测试用例 test_cases load_test_cases(TEST_LABELS_FILE)3.3 第三步调用模型API进行识别这是脚本的核心功能负责把图片发送给模型并拿回结果。def call_model_api(image_path, api_url): 调用模型API进行图片识别 try: # 以二进制形式打开图片文件 with open(image_path, rb) as img_file: files {image: img_file} # 发送POST请求通常图像识别API使用multipart/form-data格式 response requests.post(api_url, filesfiles, timeout30) # 设置超时时间 # 检查HTTP响应状态 response.raise_for_status() # 解析返回的JSON数据 result response.json() # 假设API返回格式为 {predicted_label: 向日葵品种A, confidence: 0.98} predicted_label result.get(predicted_label, ) confidence result.get(confidence, 0.0) return predicted_label, confidence, None # 第三个返回值为错误信息成功时为None except requests.exceptions.RequestException as req_err: error_msg f网络请求失败: {req_err} return None, None, error_msg except json.JSONDecodeError as json_err: error_msg f解析模型返回结果失败: {json_err} return None, None, error_msg except Exception as e: error_msg f调用API时发生未知错误: {e} return None, None, error_msg3.4 第四步批量测试与结果比对现在我们遍历所有测试用例调用上面的函数并比对结果。def run_batch_test(test_cases, images_dir, api_url): 批量运行测试并比对结果 results [] total_cases len(test_cases) for idx, (img_name, true_label) in enumerate(test_cases, 1): image_path os.path.join(images_dir, img_name) if not os.path.exists(image_path): print(f警告图片文件不存在 {image_path}跳过。) results.append({ image_name: img_name, true_label: true_label, predicted_label: FILE_NOT_FOUND, confidence: 0.0, is_correct: False, error: Image file not found }) continue print(f正在处理 [{idx}/{total_cases}]: {img_name} ...) pred_label, confidence, error call_model_api(image_path, api_url) if error: # API调用出错 is_correct False print(f 失败: {error}) else: # 比对预测标签和真实标签 (假设标签是字符串直接比对) is_correct (str(pred_label).strip() str(true_label).strip()) status 正确 if is_correct else 错误 print(f 预测: {pred_label} (置信度: {confidence:.3f}) | 真实: {true_label} - {status}) results.append({ image_name: img_name, true_label: true_label, predicted_label: pred_label if not error else API_ERROR, confidence: confidence if not error else 0.0, is_correct: is_correct, error: error }) return results3.5 第五步生成测试报告测试跑完了我们需要一份清晰的报告。这里生成一个简单的HTML报告也可以用Markdown。def generate_html_report(results, report_dir, accuracy, test_time): 生成HTML格式的测试报告 # 将结果列表转换为DataFrame方便统计 df_results pd.DataFrame(results) # 计算详细统计 total len(df_results) correct df_results[is_correct].sum() failed total - correct accuracy_percent accuracy * 100 # 生成报告文件名包含时间戳 report_filename fmodel_test_report_{test_time.strftime(%Y%m%d_%H%M%S)}.html report_path os.path.join(report_dir, report_filename) # 简单的HTML内容 html_content f !DOCTYPE html html head titleSUNFLOWER MATCH LAB 模型测试报告/title style body {{ font-family: Arial, sans-serif; margin: 40px; }} .summary {{ background-color: #f4f4f4; padding: 20px; border-radius: 5px; margin-bottom: 30px; }} .accuracy {{ font-size: 24px; font-weight: bold; color: {green if accuracy ACCURACY_ALERT_THRESHOLD else red}; }} table {{ border-collapse: collapse; width: 100%; }} th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }} th {{ background-color: #f2f2f2; }} tr:nth-child(even) {{ background-color: #f9f9f9; }} .correct {{ color: green; }} .error {{ color: red; }} /style /head body h1SUNFLOWER MATCH LAB 自动化测试报告/h1 p测试时间: {test_time.strftime(%Y-%m-%d %H:%M:%S)}/p div classsummary h2测试概览/h2 p总测试用例: strong{total}/strong/p p识别正确: strong{correct}/strong/p p识别错误/失败: strong{failed}/strong/p p准确率: span classaccuracy{accuracy_percent:.2f}%/span/p p告警阈值: strong{ACCURACY_ALERT_THRESHOLD*100:.0f}%/strong/p p状态: strong{正常 if accuracy ACCURACY_ALERT_THRESHOLD else 异常需检查}/strong/p /div h2详细结果/h2 table tr th图片名/th th真实标签/th th预测标签/th th置信度/th th结果/th th错误信息/th /tr # 添加每一行的结果 for _, row in df_results.iterrows(): result_class correct if row[is_correct] else error result_text 正确 if row[is_correct] else 错误 error_info row[error] if pd.notna(row[error]) else conf f{row[confidence]:.3f} if row[confidence] 0 else N/A html_content f tr td{row[image_name]}/td td{row[true_label]}/td td{row[predicted_label]}/td td{conf}/td td class{result_class}{result_text}/td td{error_info}/td /tr html_content /table /body /html # 写入文件 with open(report_path, w, encodingutf-8) as f: f.write(html_content) print(f测试报告已生成: {report_path}) return report_path, accuracy3.6 第六步实现告警机制当准确率不达标时我们需要让脚本“喊”出来。这里以邮件告警为例。def send_alert_email(accuracy, report_path, test_time): 发送告警邮件 if not ENABLE_EMAIL_ALERT: return from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import smtplib subject f[告警] SUNFLOWER MATCH LAB 模型准确率下降 ({accuracy*100:.2f}%) body f 模型自动化测试发现准确率低于阈值。 测试时间: {test_time.strftime(%Y-%m-%d %H:%M:%S)} 当前准确率: {accuracy*100:.2f}% 告警阈值: {ACCURACY_ALERT_THRESHOLD*100:.0f}% 详细测试报告请查看附件或访问服务器路径 {report_path} 请及时检查模型服务状态或数据是否出现漂移。 msg MIMEMultipart() msg[From] SENDER_EMAIL msg[To] , .join(RECEIVER_EMAILS) msg[Subject] subject msg.attach(MIMEText(body, plain)) try: # 这里以使用SMTP服务器发送为例具体配置需根据邮箱服务商调整 server smtplib.SMTP(SMTP_SERVER, SMTP_PORT) server.starttls() # 安全连接 server.login(SENDER_EMAIL, SENDER_PASSWORD) server.send_message(msg) server.quit() print(告警邮件发送成功。) except Exception as e: print(f发送告警邮件失败: {e})3.7 第七步组装主函数并定时执行最后我们把所有功能组装起来并加上定时执行的逻辑。def main(): 主函数执行一次完整的测试流程 print(*50) print(开始执行 SUNFLOWER MATCH LAB 模型自动化测试...) print(*50) test_start_time datetime.now() # 1. 加载测试用例 test_cases load_test_cases(TEST_LABELS_FILE) if not test_cases: print(未加载到测试用例程序退出。) return # 2. 执行批量测试 results run_batch_test(test_cases, TEST_IMAGES_DIR, MODEL_API_URL) # 3. 统计准确率 df_results pd.DataFrame(results) # 只统计没有发生错误的用例 valid_results df_results[df_results[error].isna()] if len(valid_results) 0: accuracy valid_results[is_correct].mean() else: accuracy 0.0 print(警告所有测试用例均调用失败无法计算准确率。) print(f\n测试完成。有效测试数: {len(valid_results)} 识别准确率: {accuracy*100:.2f}%) # 4. 生成报告 report_path, final_accuracy generate_html_report(results, REPORT_DIR, accuracy, test_start_time) # 5. 检查并触发告警 if final_accuracy ACCURACY_ALERT_THRESHOLD: print(f准确率 {final_accuracy*100:.2f}% 低于阈值 {ACCURACY_ALERT_THRESHOLD*100:.0f}%触发告警。) send_alert_email(final_accuracy, report_path, test_start_time) else: print(模型准确率正常。) print(自动化测试流程结束。) if __name__ __main__: # 直接运行一次 main() # 如果需要定时运行例如每6小时一次可以使用schedule库 # import schedule # import time # schedule.every(6).hours.do(main) # print(定时测试任务已启动每6小时运行一次...) # while True: # schedule.run_pending() # time.sleep(60)4. 让脚本在后台持续运行脚本写好了怎么让它长期在服务器上自动工作呢这里有几个常见的做法使用Linux Crontab这是最经典、最稳定的方式。在服务器上使用crontab -e命令添加一条定时任务即可。例如每天凌晨2点运行一次0 2 * * * cd /path/to/your/script /usr/bin/python3 model_test_script.py /var/log/model_test.log 21使用Python Schedule库守护进程就像上面代码注释里写的那样让脚本自己循环使用schedule库管理定时任务。然后使用nohup或systemd让脚本在后台运行。集成到CI/CD流水线如果你的模型更新是通过自动化流程发布的可以在发布流水线中加入这个测试脚本作为“冒烟测试”或“验收测试”的一环确保新版本模型上线前的基本质量。5. 总结与后续优化建议这套自动化测试脚本用下来确实成了我们保障模型服务质量的“定心丸”。它把原本需要人工定期检查的重复劳动自动化了一旦模型识别效果出现波动我们能在第一时间收到通知排查问题是数据的原因、服务的原因还是模型本身的原因。脚本本身也有不少可以继续完善的地方。比如测试数据集可以设计得更科学定期加入一些新的、能反映当前线上数据分布的样本防止测试集过时。告警方式也可以更丰富除了邮件还能接入钉钉、企业微信、Slack等团队常用的协作工具。报告也可以做得更美观甚至加入准确率的历史趋势图让我们能更直观地看到模型性能的变化曲线。最重要的是这套框架是通用的。今天我们用它在SUNFLOWER MATCH LAB上做图像识别测试明天稍微改改API调用和结果解析的部分就能套用到其他模型服务上比如文本分类、语音识别等等。它本质上是一套模型服务的健康监控方案。如果你也在为模型上线后的稳定性发愁不妨从这样一个简单的自动化测试脚本开始。先从核心的批量调用和结果比对功能做起让它跑起来然后再根据实际需求慢慢添加告警、报告、定时任务这些功能。有了这个基础工具你就能更从容地应对模型服务运维中的各种挑战了。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。
SUNFLOWER MATCH LAB 自动化测试:编写Python脚本进行模型批量识别与结果验证
SUNFLOWER MATCH LAB 自动化测试编写Python脚本进行模型批量识别与结果验证最近在跟进一个图像识别项目模型部署上线后最让人头疼的就是怎么知道它一直“健康”呢总不能天天手动上传图片去测吧。今天就来聊聊我们是怎么用Python写了个自动化测试脚本像给模型做“定期体检”一样确保SUNFLOWER MATCH LAB服务在生产环境里稳定可靠。简单说这个脚本的核心任务就是定时、自动地拿一批我们事先知道答案的图片去“考”模型然后自动批改试卷算出分数准确率最后生成一份体检报告。一旦发现模型“成绩”下滑立马发警报让我们能第一时间介入处理。这套方法特别适合那些已经上线、需要持续监控的模型服务能有效避免因为数据漂移或服务异常导致的线上问题。1. 为什么需要自动化测试模型部署上线只是万里长征第一步。线上环境复杂多变今天表现好好的模型明天可能因为各种原因“状态不佳”。比如新来的数据分布和训练时不一样了或者服务器资源波动影响了推理速度甚至代码更新引入了意想不到的Bug。手动测试效率低、不及时还容易出错。我们需要的是一套能7x24小时工作的“哨兵”系统。自动化测试脚本就是这个哨兵它能定期、客观地评估模型状态把我们从重复的体力劳动中解放出来更专注于分析问题和优化模型。2. 设计我们的自动化测试方案在动手写代码之前我们先得把整个流程想清楚。一个好的自动化测试方案应该包含下面几个关键部分。2.1 核心流程梳理整个测试过程可以概括为“准备-执行-验证-报告”四步曲准备阶段准备好一批测试图片并且每张图片都要有正确的标签也就是我们期望模型识别出的结果。这些图片最好能覆盖模型要识别的所有类别并且包含一些容易出错的边缘案例。执行阶段编写脚本自动将这些测试图片一张张或者一批批地发送给SUNFLOWER MATCH LAB的识别接口。验证阶段脚本接收模型返回的识别结果然后和我们事先准备好的正确标签进行比对判断每个识别是对是错。报告与告警阶段统计总的识别准确率生成一份清晰易懂的测试报告比如HTML或Markdown格式。更重要的是设定一个准确率阈值比如95%一旦低于这个阈值就自动触发告警通过邮件、钉钉、企业微信等方式通知相关人员。2.2 测试数据准备测试数据是评估的基石。我们专门维护了一个测试图片集。这个数据集有几点讲究代表性要包含模型所有需要识别的类别。比如SUNFLOWER MATCH LAB是用来识别不同品种向日葵的那么测试集里就应该有所有目标品种的图片。多样性同一品种的图片要有不同角度、不同光照、不同背景的模拟真实场景。挑战性可以故意放一些模糊的、有遮挡的、或者类别间比较相似的图片看看模型的“抗压能力”如何。标签准确每一张图片的标签都必须人工核对确保100%正确这是评判模型对错的“标准答案”。我们把这些图片和对应的标签文件比如一个CSV文件或JSON文件放在一个固定的目录里方便脚本读取。2.3 技术工具选型实现这个方案我们主要用到Python的几个常用库它们就像我们工具箱里的得力助手requests负责和SUNFLOWER MATCH LAB的HTTP API进行通信发送图片接收识别结果。PIL(Pillow) 或opencv-python用来在发送前对图片进行一些必要的预处理比如调整大小、转换格式或者只是简单地打开图片。pandas如果测试用例很多用这个库来管理测试用例的标签和最终的比对结果非常方便读写CSV文件、做数据统计都很简单。smtplibemail(Python内置)用于实现邮件告警功能。json用于解析模型返回的JSON格式的结果。schedule或crontab实现定时任务。schedule库适合在脚本内部实现简单的定时循环而Linux系统的crontab则更常用于部署生产环境的定时任务。3. 分步编写Python测试脚本接下来我们一步步把想法变成代码。我会把关键代码贴出来并加上详细注释。3.1 第一步配置与准备首先我们把一些固定的信息配置好比如模型服务的地址、测试数据的位置等。import os import json import pandas as pd from PIL import Image import requests from datetime import datetime # 配置区域 # 1. 模型服务API地址 MODEL_API_URL http://your-sunflower-match-lab-server:port/predict # 请替换为实际地址 # 2. 测试数据集路径 TEST_IMAGES_DIR ./test_dataset/images # 存放测试图片的文件夹 TEST_LABELS_FILE ./test_dataset/labels.csv # 存放图片名和对应正确标签的CSV文件 # 3. 报告输出路径 REPORT_DIR ./test_reports # 4. 告警阈值 (准确率低于此值则触发告警) ACCURACY_ALERT_THRESHOLD 0.95 # 95% # 5. 邮件告警配置 (如果需要) ENABLE_EMAIL_ALERT False SMTP_SERVER smtp.your-email.com SMTP_PORT 587 SENDER_EMAIL your-alertemail.com SENDER_PASSWORD your-password RECEIVER_EMAILS [team-member1email.com, team-member2email.com] # 确保报告目录存在 os.makedirs(REPORT_DIR, exist_okTrue)3.2 第二步加载测试用例我们假设标签文件是一个CSV里面有两列image_name图片文件名和true_label正确标签。def load_test_cases(label_file_path): 加载测试用例图片名和真实标签 try: df pd.read_csv(label_file_path) # 假设CSV文件包含 image_name 和 true_label 列 test_cases list(zip(df[image_name], df[true_label])) print(f成功加载 {len(test_cases)} 个测试用例。) return test_cases except FileNotFoundError: print(f错误未找到标签文件 {label_file_path}) return [] except Exception as e: print(f加载标签文件时发生错误{e}) return [] # 加载测试用例 test_cases load_test_cases(TEST_LABELS_FILE)3.3 第三步调用模型API进行识别这是脚本的核心功能负责把图片发送给模型并拿回结果。def call_model_api(image_path, api_url): 调用模型API进行图片识别 try: # 以二进制形式打开图片文件 with open(image_path, rb) as img_file: files {image: img_file} # 发送POST请求通常图像识别API使用multipart/form-data格式 response requests.post(api_url, filesfiles, timeout30) # 设置超时时间 # 检查HTTP响应状态 response.raise_for_status() # 解析返回的JSON数据 result response.json() # 假设API返回格式为 {predicted_label: 向日葵品种A, confidence: 0.98} predicted_label result.get(predicted_label, ) confidence result.get(confidence, 0.0) return predicted_label, confidence, None # 第三个返回值为错误信息成功时为None except requests.exceptions.RequestException as req_err: error_msg f网络请求失败: {req_err} return None, None, error_msg except json.JSONDecodeError as json_err: error_msg f解析模型返回结果失败: {json_err} return None, None, error_msg except Exception as e: error_msg f调用API时发生未知错误: {e} return None, None, error_msg3.4 第四步批量测试与结果比对现在我们遍历所有测试用例调用上面的函数并比对结果。def run_batch_test(test_cases, images_dir, api_url): 批量运行测试并比对结果 results [] total_cases len(test_cases) for idx, (img_name, true_label) in enumerate(test_cases, 1): image_path os.path.join(images_dir, img_name) if not os.path.exists(image_path): print(f警告图片文件不存在 {image_path}跳过。) results.append({ image_name: img_name, true_label: true_label, predicted_label: FILE_NOT_FOUND, confidence: 0.0, is_correct: False, error: Image file not found }) continue print(f正在处理 [{idx}/{total_cases}]: {img_name} ...) pred_label, confidence, error call_model_api(image_path, api_url) if error: # API调用出错 is_correct False print(f 失败: {error}) else: # 比对预测标签和真实标签 (假设标签是字符串直接比对) is_correct (str(pred_label).strip() str(true_label).strip()) status 正确 if is_correct else 错误 print(f 预测: {pred_label} (置信度: {confidence:.3f}) | 真实: {true_label} - {status}) results.append({ image_name: img_name, true_label: true_label, predicted_label: pred_label if not error else API_ERROR, confidence: confidence if not error else 0.0, is_correct: is_correct, error: error }) return results3.5 第五步生成测试报告测试跑完了我们需要一份清晰的报告。这里生成一个简单的HTML报告也可以用Markdown。def generate_html_report(results, report_dir, accuracy, test_time): 生成HTML格式的测试报告 # 将结果列表转换为DataFrame方便统计 df_results pd.DataFrame(results) # 计算详细统计 total len(df_results) correct df_results[is_correct].sum() failed total - correct accuracy_percent accuracy * 100 # 生成报告文件名包含时间戳 report_filename fmodel_test_report_{test_time.strftime(%Y%m%d_%H%M%S)}.html report_path os.path.join(report_dir, report_filename) # 简单的HTML内容 html_content f !DOCTYPE html html head titleSUNFLOWER MATCH LAB 模型测试报告/title style body {{ font-family: Arial, sans-serif; margin: 40px; }} .summary {{ background-color: #f4f4f4; padding: 20px; border-radius: 5px; margin-bottom: 30px; }} .accuracy {{ font-size: 24px; font-weight: bold; color: {green if accuracy ACCURACY_ALERT_THRESHOLD else red}; }} table {{ border-collapse: collapse; width: 100%; }} th, td {{ border: 1px solid #ddd; padding: 12px; text-align: left; }} th {{ background-color: #f2f2f2; }} tr:nth-child(even) {{ background-color: #f9f9f9; }} .correct {{ color: green; }} .error {{ color: red; }} /style /head body h1SUNFLOWER MATCH LAB 自动化测试报告/h1 p测试时间: {test_time.strftime(%Y-%m-%d %H:%M:%S)}/p div classsummary h2测试概览/h2 p总测试用例: strong{total}/strong/p p识别正确: strong{correct}/strong/p p识别错误/失败: strong{failed}/strong/p p准确率: span classaccuracy{accuracy_percent:.2f}%/span/p p告警阈值: strong{ACCURACY_ALERT_THRESHOLD*100:.0f}%/strong/p p状态: strong{正常 if accuracy ACCURACY_ALERT_THRESHOLD else 异常需检查}/strong/p /div h2详细结果/h2 table tr th图片名/th th真实标签/th th预测标签/th th置信度/th th结果/th th错误信息/th /tr # 添加每一行的结果 for _, row in df_results.iterrows(): result_class correct if row[is_correct] else error result_text 正确 if row[is_correct] else 错误 error_info row[error] if pd.notna(row[error]) else conf f{row[confidence]:.3f} if row[confidence] 0 else N/A html_content f tr td{row[image_name]}/td td{row[true_label]}/td td{row[predicted_label]}/td td{conf}/td td class{result_class}{result_text}/td td{error_info}/td /tr html_content /table /body /html # 写入文件 with open(report_path, w, encodingutf-8) as f: f.write(html_content) print(f测试报告已生成: {report_path}) return report_path, accuracy3.6 第六步实现告警机制当准确率不达标时我们需要让脚本“喊”出来。这里以邮件告警为例。def send_alert_email(accuracy, report_path, test_time): 发送告警邮件 if not ENABLE_EMAIL_ALERT: return from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart import smtplib subject f[告警] SUNFLOWER MATCH LAB 模型准确率下降 ({accuracy*100:.2f}%) body f 模型自动化测试发现准确率低于阈值。 测试时间: {test_time.strftime(%Y-%m-%d %H:%M:%S)} 当前准确率: {accuracy*100:.2f}% 告警阈值: {ACCURACY_ALERT_THRESHOLD*100:.0f}% 详细测试报告请查看附件或访问服务器路径 {report_path} 请及时检查模型服务状态或数据是否出现漂移。 msg MIMEMultipart() msg[From] SENDER_EMAIL msg[To] , .join(RECEIVER_EMAILS) msg[Subject] subject msg.attach(MIMEText(body, plain)) try: # 这里以使用SMTP服务器发送为例具体配置需根据邮箱服务商调整 server smtplib.SMTP(SMTP_SERVER, SMTP_PORT) server.starttls() # 安全连接 server.login(SENDER_EMAIL, SENDER_PASSWORD) server.send_message(msg) server.quit() print(告警邮件发送成功。) except Exception as e: print(f发送告警邮件失败: {e})3.7 第七步组装主函数并定时执行最后我们把所有功能组装起来并加上定时执行的逻辑。def main(): 主函数执行一次完整的测试流程 print(*50) print(开始执行 SUNFLOWER MATCH LAB 模型自动化测试...) print(*50) test_start_time datetime.now() # 1. 加载测试用例 test_cases load_test_cases(TEST_LABELS_FILE) if not test_cases: print(未加载到测试用例程序退出。) return # 2. 执行批量测试 results run_batch_test(test_cases, TEST_IMAGES_DIR, MODEL_API_URL) # 3. 统计准确率 df_results pd.DataFrame(results) # 只统计没有发生错误的用例 valid_results df_results[df_results[error].isna()] if len(valid_results) 0: accuracy valid_results[is_correct].mean() else: accuracy 0.0 print(警告所有测试用例均调用失败无法计算准确率。) print(f\n测试完成。有效测试数: {len(valid_results)} 识别准确率: {accuracy*100:.2f}%) # 4. 生成报告 report_path, final_accuracy generate_html_report(results, REPORT_DIR, accuracy, test_start_time) # 5. 检查并触发告警 if final_accuracy ACCURACY_ALERT_THRESHOLD: print(f准确率 {final_accuracy*100:.2f}% 低于阈值 {ACCURACY_ALERT_THRESHOLD*100:.0f}%触发告警。) send_alert_email(final_accuracy, report_path, test_start_time) else: print(模型准确率正常。) print(自动化测试流程结束。) if __name__ __main__: # 直接运行一次 main() # 如果需要定时运行例如每6小时一次可以使用schedule库 # import schedule # import time # schedule.every(6).hours.do(main) # print(定时测试任务已启动每6小时运行一次...) # while True: # schedule.run_pending() # time.sleep(60)4. 让脚本在后台持续运行脚本写好了怎么让它长期在服务器上自动工作呢这里有几个常见的做法使用Linux Crontab这是最经典、最稳定的方式。在服务器上使用crontab -e命令添加一条定时任务即可。例如每天凌晨2点运行一次0 2 * * * cd /path/to/your/script /usr/bin/python3 model_test_script.py /var/log/model_test.log 21使用Python Schedule库守护进程就像上面代码注释里写的那样让脚本自己循环使用schedule库管理定时任务。然后使用nohup或systemd让脚本在后台运行。集成到CI/CD流水线如果你的模型更新是通过自动化流程发布的可以在发布流水线中加入这个测试脚本作为“冒烟测试”或“验收测试”的一环确保新版本模型上线前的基本质量。5. 总结与后续优化建议这套自动化测试脚本用下来确实成了我们保障模型服务质量的“定心丸”。它把原本需要人工定期检查的重复劳动自动化了一旦模型识别效果出现波动我们能在第一时间收到通知排查问题是数据的原因、服务的原因还是模型本身的原因。脚本本身也有不少可以继续完善的地方。比如测试数据集可以设计得更科学定期加入一些新的、能反映当前线上数据分布的样本防止测试集过时。告警方式也可以更丰富除了邮件还能接入钉钉、企业微信、Slack等团队常用的协作工具。报告也可以做得更美观甚至加入准确率的历史趋势图让我们能更直观地看到模型性能的变化曲线。最重要的是这套框架是通用的。今天我们用它在SUNFLOWER MATCH LAB上做图像识别测试明天稍微改改API调用和结果解析的部分就能套用到其他模型服务上比如文本分类、语音识别等等。它本质上是一套模型服务的健康监控方案。如果你也在为模型上线后的稳定性发愁不妨从这样一个简单的自动化测试脚本开始。先从核心的批量调用和结果比对功能做起让它跑起来然后再根据实际需求慢慢添加告警、报告、定时任务这些功能。有了这个基础工具你就能更从容地应对模型服务运维中的各种挑战了。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。