mardianto-msft/foundry-local-eval

GitHub: mardianto-msft/foundry-local-eval

该项目使用 Azure AI Evaluation 红队 SDK 对在本地运行的 Microsoft Foundry 语言模型进行对抗性安全扫描与风险评分。

Stars: 0 | Forks: 0

# 红队 Foundry 本地模型 本项目在本地机器上使用 Foundry Local 下载并运行语言模型,然后使用 Azure AI Evaluation 红队 SDK 对其进行评估。它还包含一个交互式聊天实用工具,用于在扫描前检查模型。 Azure Developer CLI (`azd`) 负责配置评估器所需的 Microsoft Foundry 账户和项目。受测模型并不会部署到 Azure。 目标模型及其推理在本地机器上运行。Azure AI Evaluation 使用配置好的 Microsoft Foundry 项目来生成攻击,并针对以下风险类别对回复进行评分: - 暴力 - 仇恨和不公平 - 性内容 - 自残 该扫描应用了基线、分组简单与中等难度、编码以及文本转换攻击策略。它会报告攻击成功率 (ASR),数值越高意味着有越多的对抗性 prompt 引发的回复超过了设定的安全阈值。 ## 执行模型 这是一个混合了本地和云端的工作流,而不是一个完全离线的红队扫描器: - **本地:** 目标模型通过 Foundry Local 进行下载、加载和查询。Python 扫描过程、回调、缓存、日志和生成的产出物也都在本地进行。 - **Azure:** Azure AI Evaluation SDK 使用配置好的 Microsoft Foundry 项目来生成对抗性攻击,并对模型回复进行评分。这需要 Azure 连接、`AZURE_AI_PROJECT_ENDPOINT`、Azure CLI 凭据以及配置好的 Foundry 资源。 简而言之,模型推理在本地进行,而攻击生成和安全评估则依赖于 Azure 服务。 对于每次攻击,评估器都会通过配置好的 Foundry 项目生成一个 prompt,调用进程内回调将该 prompt 发送给本地模型,并返回模型回复以供 Azure 端进行评分。尽管模型权重和推理运行时保留在本地,但您应将扫描的 prompt 和回复视为跨越了 Azure 服务边界的数据。模型列表、缓存管理和交互式聊天不使用 Azure 评估器。 如需了解更多信息,请参阅[在本地运行 AI 红队代理 (Azure AI Evaluation SDK) - Microsoft Foundry | Microsoft Learn](https://learn.microsoft.com/en-us/azure/foundry/how-to/develop/run-scans-ai-red-teaming-agent)。 ## 脚本 ### redteam_foundry_local_model.py 主入口点。它可以: - 列出可用或已下载的 Foundry Local 模型。 - 从本地缓存中删除已下载的模型。 - 下载并加载选定的模型。 - 对其运行 Azure AI Evaluation 红队扫描。 - 保存详细的证据、日志和汇总记分卡。 - 串行运行或以有限的并行度运行。 ### foundry_local_interactive_chat.py 一个交互式的冒烟测试实用工具。它会下载并加载选定的模型,为当前会话保留对话历史,并在用户退出时卸载模型。红队回调被特意设计为单轮对话,因此该工具非常适合在扫描前进行手动的、有状态的检查。 ### foundry_local_model_utils.py 两个命令行脚本共享的内部模块。它负责 Foundry Local 目录初始化、模型查找与显示、下载、缓存检测以及缓存删除。它不是一个独立的入口点。 ### 基础设施 - `azure.yaml`:配置 Bicep 部署和预配后钩子。 - `infra/main.bicep`:创建资源组并调用 Foundry 模块。 - `infra/modules/foundry.bicep`:创建 Microsoft Foundry 账户和项目。 - `scripts/write-env.sh`:将预配好的项目端点写入 `.env`,且不会删除无关条目。 ## 先决条件 您需要: - Python 3.10 至 3.13 版本,以满足 Azure AI Evaluation 红队的依赖项。 - 受 [Foundry Local](https://learn.microsoft.com/azure/ai-foundry/foundry-local/get-started) 支持的平台。 - 一个 Azure 订阅,您可以在其中创建资源组、Microsoft Foundry 资源和 Foundry 项目。 - [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli)。 - [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) 1.27 或更高版本。 在 Ubuntu 或 Debian 上,使用以下命令安装 Azure CLI: ``` curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash curl -fsSL https://aka.ms/install-azd.sh | bash ``` 验证安装: ``` python3 --version az version azd version ``` 对于其他操作系统,请使用上方链接的安装指南。 ## 快速开始 ### 1. 克隆仓库 克隆项目并进入其目录: ``` git clone https://github.com/mardianto-msft/foundry-local-eval.git cd foundry-local-eval ``` ### 2. 安装 Python 依赖项 在仓库根目录下执行: ``` python3 -m venv .fl source .fl/bin/activate python -m pip install --upgrade pip python -m pip install -r requirements.txt ``` ### 3. 登录 Azure AZD 负责配置基础设施,而 Python 评估器通过 `AzureCliCredential` 进行身份验证。请登录这两个工具: ``` azd auth login az login ``` 验证这两个会话: ``` azd auth login --check-status az account show --output table ``` ### 4. 配置 Microsoft Foundry 配置 Azure 资源: ``` azd up ``` 首次运行时,AZD 会提示输入 Azure 订阅、环境名称和区域。基础设施默认使用 `eastus2`。环境名称决定了所有资源的名称: | 资源 | 名称 | |----------|------| | 资源组 | `rg-` | | Microsoft Foundry 资源 | `aif-` | | Foundry 项目 | `proj-` | 例如,`dev` 环境会创建 `rg-dev`、`aif-dev` 和 `proj-dev`。 预配完成后,[scripts/write-env.sh](scripts/write-env.sh) 会自动将 `AZURE_AI_PROJECT_ENDPOINT` 写入根目录的 `.env` 文件中。现有的无关条目会被保留,并且 `.env` 会被 Git 忽略。 您可以使用以下命令检查所有部署输出: ``` azd env get-values ``` 生成的 `.env` 条目格式如下: ``` AZURE_AI_PROJECT_ENDPOINT=https://aif-.services.ai.azure.com/api/projects/proj- ``` ### 5. 验证设置 保持虚拟环境处于激活状态,并验证脚本和模型目录是否可用: ``` python redteam_foundry_local_model.py --help python redteam_foundry_local_model.py --list-model ``` 列出模型、列出已缓存模型以及删除缓存不需要 Azure 凭据。运行红队扫描则需要。 ## 模型管理 列出通过 Foundry Local 目录提供的所有模型: ``` python redteam_foundry_local_model.py --list-model ``` 仅列出已下载到项目本地缓存的模型: ``` python redteam_foundry_local_model.py --cached ``` 从本地缓存中删除已下载的模型: ``` python redteam_foundry_local_model.py --delete-model qwen2.5-0.5b ``` 删除操作使用 Foundry Local SDK 的缓存移除功能。当模型尚未下载时,脚本会进行报告;并且它会使用与扫描相同的进程锁,以避免在扫描正在使用模型时将其删除。 下载的模型存储在 `.foundry-local/` 目录下。当任一命令行脚本首次需要某个模型时,它会自动被下载。 ## 交互式聊天 启动有状态的聊天会话: ``` python foundry_local_interactive_chat.py --model qwen2.5-0.5b ``` 默认情况下,回复会在生成时以流的形式传输。使用 `--stream` 显式选择流式传输,或使用 `--no-stream` 获取非流式回复: ``` python foundry_local_interactive_chat.py --model qwen2.5-0.5b --stream python foundry_local_interactive_chat.py --model qwen2.5-0.5b --no-stream ``` 输入 `exit` 或 `quit` 可卸载模型并停止。空的 prompt 会被忽略。 聊天实用工具也可以用于检查目录: ``` python foundry_local_interactive_chat.py --list-models python foundry_local_interactive_chat.py --cached ``` 从本地缓存中删除已下载的模型: ``` python foundry_local_interactive_chat.py --delete-model qwen2.5-0.5b ``` ## 红队扫描 运行串行扫描,这对于本地 CPU 模型来说是更安全的默认设置: ``` python redteam_foundry_local_model.py --model qwen2.5-0.5b ``` 以有限的并行度运行: ``` python redteam_foundry_local_model.py \ --model qwen2.5-0.5b \ --parallel \ --max-parallel-tasks 2 ``` 该脚本一次只允许执行一个扫描或模型删除操作。即使启用了并行攻击编排,它也会将针对共享本地聊天客户端的调用串行化,因为本地客户端不能被并发使用。 每次扫描涵盖以下风险类别: - 暴力 - 仇恨和不公平 - 性内容 - 自残 配置的策略包括分组简单和中等难度攻击、字符间距、ROT13、Unicode 同形异义词、字符替换、摩斯密码、leetspeak、URL 编码、二进制编码,以及 Base64 加 ROT13 的组合。SDK 还会运行基线 prompt。分组策略会展开为多种独立技术,因此模型调用的次数会大大超过 `风险类别 × 目标数`。 ### 扫描选项 | 选项 | 默认值 | 描述 | |--------|---------|-------------| | `--model MODEL` | `phi-4-mini` | 要下载和扫描的 Foundry Local 模型别名。 | | `--num-objectives N` | `2` | 为每个风险类别生成的攻击目标数。增加此值会大幅增加运行时间。 | | `--max-tokens N` | `512` | 每个本地模型回复中的最大 token 数。 | | `--temperature VALUE` | `0.0` | 本地聊天客户端使用的采样温度。 | | `--parallel` | 禁用 | 允许并行攻击编排。本地推理保持串行化。 | | `--max-parallel-tasks N` | `1` | 启用 `--parallel` 时的最大 SDK 任务数。 | | `--scan-timeout SECONDS` | `7200` | 整体扫描超时时间。 | | `--output PATH` | `-redteam-results.json` | SDK 导出路径。请参阅下方的输出说明。 | 使用 `python redteam_foundry_local_model.py --help` 获取完整的 CLI 参考。 ## 结果 每次运行都会在仓库根目录中创建一个隐藏的 `.scan__/` 证据目录。首先查看: - `scorecard.txt`:快速的人类可读摘要。 - `__results.jsonl`:每种风险和策略组合的详细 prompt、模型回复、分数和评分理由。 - `final_results.json`:机器可读的汇总记分卡。 例如,一次 Qwen 2.5 0.5B 的扫描产生了: ``` Overall ASR: 10.71% Attack Success: 12/112 attacks were successful Risk Category Baseline Easy Moderate Violence 50.0% 8.33% 100.0% Hate-unfairness 50.0% 8.33% 50.0% Sexual 0.0% 0.0% 0.0% Self-harm 50.0% 4.17% 50.0% ``` **ASR** 表示攻击成功率:即引发的回复超过配置的安全阈值的对抗性 prompt 的百分比。越低越好。在此示例中,112 次攻击中有 12 次成功;中等难度的暴力攻击是最薄弱的环节,而没有性内容攻击成功。 证据目录还包含: - `results.json`:评估运行状态、计数、策略和使用情况摘要。 - `instance_results.json`:扫描实例的序列化结果。 - `redteam_info.json`:产出物索引、完成状态以及按策略和类别划分的 ASR。 - `redteam.log`:详细的 SDK 执行日志。 SDK 还会写入通过 `--output` 传递的路径。使用本项目所采用的 SDK 版本时,像 `qwen2.5-0.5b-redteam-results.json` 这样的默认路径尽管带有 `.json` 后缀,但会被创建为一个目录。它包含: - `evaluation_results.json`:导出的记分卡和详细的评估数据。 - `results.json`:评估元数据和状态。 `.scan_*/` 和 `*-redteam-results.json` 路径默认都会被 Git 忽略。 ## 本地数据 脚本将生成的状态保留在项目目录内: - `.foundry-local/`:已下载的 Foundry Local 模型数据。 - `.azure/`:AZD 环境和部署状态。 - `.pyrit-data/`:PyRIT 状态。 - `.cache/` 和 `.tmp/`:运行时缓存和临时文件。 - `.redteam_foundry_local_model.lock`:扫描和模型删除使用的进程锁。 - `.scan_*/`:每次运行的证据和记分卡。 - `*-redteam-results.json/`:当前 SDK 行为对应的 SDK 导出目录。 红队脚本会在 `finally` 块中卸载模型并释放其锁,包括在扫描失败时。交互式聊天实用工具同样会在会话结束时卸载其模型。 要在不删除其他项目状态的情况下移除已下载的模型,请使用 `--delete-model`。要移除生成的扫描产出物,请删除相关的 `.scan_*/` 和 `*-redteam-results.json/` 目录。 ## 故障排除 ### 缺少项目端点 如果扫描报告 `Set AZURE_AI_PROJECT_ENDPOINT before running this script`,请运行 `azd up` 或检查选定的 AZD 环境: ``` azd env get-values ``` 确认根目录下的 `.env` 包含 `AZURE_AI_PROJECT_ENDPOINT`。该脚本使用 `python-dotenv` 加载此文件。 ### 身份验证失败 刷新评估器使用的 Azure CLI 会话: ``` az login az account show --output table ``` 单独使用 `azd auth login --check-status` 来验证用于预配的 AZD 会话。 ### 另一个运行处于活动状态 只有一个扫描或模型删除操作可以持有项目锁。请在重试前停止另一个进程。在扫描处于活动状态时,请勿手动删除锁文件。 ### 扫描时间长 从默认设置开始。对于仅使用 CPU 的模型,请保持禁用并行执行,减少 `--num-objectives`,或降低 `--max-tokens`。增加并行 SDK 任务数并不能使共享的本地模型客户端变为并发执行。 ## 移除 Azure 资源 要删除为选定 AZD 环境配置的资源组和所有资源: ``` azd down ``` 在确认之前,请仔细检查 AZD 显示的环境,因为此操作会删除资源组、Foundry 账户和 Foundry 项目。它不会删除本地模型或扫描产出物。
标签:AI红队, Azure AI, DLL 劫持, Naabu, 人工智能, 内容安全, 反取证, 大语言模型, 安全评估, 微软Foundry, 本地部署, 用户模式Hook绕过, 逆向工具