# 隐语杯-全同态knn赛道选手指南 ## 1. 整体流程 ### 1.1. 比赛内容 本赛道赛题为基于全同态加密(FHE)技术,在加密的向量数据库内,寻找离加密的query向量最接近的向量,旨在考察选手对全同态加密的算法及工程优化能力。 真实应用场景中,查询方、数据方、计算方分属不同的角色,查询方和数据方分别使用查询方的FHE公钥加密自己的数据,送给计算方进行FHE KNN计算,结果返回给查询方解密。但本比赛为编程简便起见,简化为单个程序内模拟完成上述所有步骤。 参赛队伍可以从赛道官网下载测试数据,编写对应代码并进行测试。提交打分时我们会使用另一份相同大小的测试数据(参赛队伍不可见)进行打分评估。 总成绩=决赛成绩,初赛成绩仅决定赛队是否获得进入决赛的资格。 ### 1.2. 评分规则 #### 1.2.1. 初赛规则 以选手的代码总耗时为评分依据,耗时越短得分越高; 要求说明: 1. 参赛选手的正确率需达到90%以上(即至少有9条结果正确,顺序不限)方可获得评分,正确率低于90%则评分为0。 2. 初赛排行榜前十的队伍可进入决赛环节,参与线下答辩。 提交次数及打榜规则说明: 每支赛队总上限可以提交预测任务50次,期间当有10次成功得到分数,则剩余预测任务提交次数作废,不可再次提交。(若提交作品前10次均正常出分,将无法再提交作品,请合理安排提交策略) 提交作品时间:6月30日10:00-8月12日23:59,开榜时间:7月14日10:00 #### 1.2.2. 决赛规则 选手在线下答辩环节,根据答题指南阐述完整算法方案。由评委综合算法创新性和算法性能进行打分。 1. 安全性与隐私保护:结合参赛内容,说明在数据处理、算法运行或实际应用中,如何确保数据安全、隐私保护以及算法的鲁棒性,避免潜在的安全风险。 2. 创新性与实用性:结合实际案例或问题背景,说明KNN算法在参赛作品中的创新点和实际应用价值。 3. 算法实现细节:详细说明参赛作品中KNN算法的具体实现方式,包括数据预处理、参数选择、优化策略等。 4. 算法效果与优势:通过实验结果、对比分析等方式,展示KNN算法在参赛问题中的表现和优势。 ## 2. 操作步骤 ### 2.1. 下载测试数据 从 "赛道官网>资源入口" 下载测试数据train_data.tgz,解压得到train.jsonl。json的query部分表示query向量,data部分表示数据库。 ### 2.2. 编写同态代码 本部分可以使用任何全同态加密框架,但是参数必须满足128位安全性。 - **密钥生成**:生成一对FHE公私钥及相关评估密钥(若有)。 - **数据加密**:从--dataset 入参读入train.jsonl,并进行FHE加密。query和data都要加密。可以先对query和data进行预处理(如设计编码)再加密,但是本步骤是模拟查询方和数据方各自加密自己的数据内容,因此对query的预处理不能利用data的内容,对data的预处理不能利用query的内容,只有数据格式(长度、位宽)是公开的。违反者将被判负,故意作弊(例如直接计算明文距离)的队伍将被公示! - **同态查询**:对FHE加密的查询向量和数据库实施KNN查询,返回十条加密数据。注意返回结果中只能包含十条加密数据,如果结果中含有比十条数据更多的信息,需要将它们清理掉(置0或者随机数)。本步骤是模拟查询方和数据方之外的第三方进行计算,因此查询过程不能假设已知FHE私钥。违反者将被判负。 **注意**:程序内存使用请不要超过32G,因为比赛平台为每个容器只分配32G内存。 - **结果输出**:对上述查询返回的十条加密结果使用FHE私钥进行解密。将这十条数据的行号(第一行的行号为1)按照jsonl格式输出到--predictions 指定的文件位置。本步骤只包含解密,不能进行计算,且不能利用结果中除这十条数据之外的任何数据内容。 样例: ```json { "answer": [3, 2, 1, 4, 5, 7, 6, 8, 9, 10] } ``` ### 2.3. (可选)记录日志 选手可以选择将一些关键信息输出到日志,该日志会在比赛平台网页上展示,以便万一自动打分失败时寻找原因。python样例代码如下: ```python import logging import os # 设置日志配置 log_file_path = '/home/admin/workspace/job/logs/user.log' os.makedirs(os.path.dirname(log_file_path), exist_ok=True) # 确保日志目录存在 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_file_path), logging.StreamHandler() # 同时输出到控制台 ] ) try: .... # 这里是选手的代码 except Exception as e: logging.error(f"出现异常: {str(e)}") exit(10) ``` ### 2.4. 编写入口run.sh 编写完程序后,请按照如下格式编写run.sh文件。该文件会被自动调用用以打分。 ```bash #!/bin/bash SCRIPT_DIR=$(dirname "$0") PARENT_DIR="$(dirname "$SCRIPT_DIR")" # 根据运行环境选择文件路径 if [ "$ALIPAY_APP_ENV" = "prod" ]; then PREDICTIONS_RESULT_FILE="/home/admin/workspace/job/output/predictions/predictions.jsonl" DATASET_FILE="/home/admin/workspace/job/input/test.jsonl" else PREDICTIONS_RESULT_FILE="${PARENT_DIR}/data/predictions.jsonl" DATASET_FILE="${PARENT_DIR}/data/data.jsonl" fi echo $PREDICTIONS_RESULT_FILE #以上内容**不可**修改! #选手仅可修改下面的test为自己的实际比赛代码入口 chmod +x "${SCRIPT_DIR}/test" "${SCRIPT_DIR}/test" \ --dataset "$DATASET_FILE" \ --predictions "$PREDICTIONS_RESULT_FILE" ``` ### 2.5. 打包镜像 编写Dockerfile(以下以gcc:latest作为基础镜像为例) ```dockerfile FROM gcc:latest RUN git clone ....(安装所需的软件) ``` Dockerfile中需要将run.sh、比赛可执行文件、测试数据train.jsonl分别拷贝到镜像的以下位置。 ```dockerfile COPY run.sh /home/admin/predict/run.sh RUN chmod 777 /home/admin/predict/run.sh COPY test /home/admin/predict/test COPY train.jsonl /home/admin/data/data.jsonl ``` ### 2.6. 测试(非常重要!) 进入镜像(请替换your_image_name为你的镜像名称): ```bash docker run -it your_image_name ``` 使用绝对路径运行run.sh, ```bash /home/admin/predict/run.sh ``` 应能自动创建文件/home/admin/data/predictions.jsonl,并在其中正确输出json格式的预期结果(下述仅为示例)。 ```bash #cat /home/admin/data/predictions.jsonl { "answer": [ 3, 2, 1, 4, 5, 7, 6, 8, 9, 10 ] } ``` 另外因为打分脚本是python,所以请确保镜像安装了python,版本为3.x以上: ```bash # python --version Python 3.9.0 ``` ## 3. 提交镜像 确认2.6中的测试无误后,可以上传镜像到比赛服务器。建议使用阿里云个人镜像(免费)。 ### 3.1. 阿里云账号注册、登录 在aliyun.com注册账号并登陆容器镜像服务控制台,https://cr.console.aliyun.com/。 ### 3.2. 新建个人镜像空间 1. 在顶部菜单栏,选择所需地域。 2. 在左侧导航栏,选择实例列表。 3. 在实例列表页面,单击个人版区域任意位置。 4. 在提示对话框单击创建个人版。 5. 在容器镜像服务实例创建页面,选择一个区域,单击立即创建。 6. 实例创建成功后,在控制台中点击进入实例。 7. 按照右下角新手指引创建镜像仓库。 ### 3.3. 上传镜像到个人镜像空间 在控制台中使用访问凭证登录阿里云容器镜像服务。以下例子使用的是香港区域,请修改为你的正确区域。请将your_account_name修改为你的阿里云账号邮箱。 ```bash docker login --username=your_account_name registry.cn-hongkong.aliyuncs.com ``` 将你的镜像名称标记为你的阿里云容器镜像服务中的对应名称。请将your_image_name修改为你的本地镜像名称,your_name_space修改为你的命名空间,your_repo修改为你的仓库名称,your_version修改为你的镜像版本号(建议从1.0开始,修改一次递增为2.0,类推)。 ```bash docker tag your_image_name registry.cn-hongkong.aliyuncs.com/your_name_space/your_repo:your_version ``` 将镜像上传到阿里云服务器。 ```bash docker push registry.cn-hongkong.aliyuncs.com/your_name_space/your_repo:your_version ``` ### 3.4. 提交赛题 在比赛网页中点击配置路径。 填写你的阿里云镜像名称。处理节点选择北京。注意如果在阿里云容器镜像服务>镜像仓库>管理中设置了仓库类型是公开,则可以不用输入用户名和密码。否则请在用户名和密码栏中输入你的阿里云账号名称和访问凭证(是容器镜像服务中创建的访问凭证,不是阿里云账号密码)。 配置好路径提交之后,记得在这里点击确认提交。注意每个队伍只有有限次提交出分的机会,一定要本地通过2.6测试之后再提交! ## 4. 提交writeup文档及代码 鉴于自动评分系统无法确认实际密码算法的安全性,我们会对排名靠前的选手进行人工检查。因此选手还需要将自己的代码和writeup文档打包为一个zip文件,从如下入口上传。 writeup文档应包含以下内容,格式pdf或word随意: - 介绍所选择的FHE算法、FHE库、参数大小(N,q等),并指出其在代码中的位置; - 简要介绍KNN算法的内容(如何比较距离,如何选择最近的10个结果) - 选手本地测试耗时。