2025年1月

一些评估测试集

这是
自动评估基准
系列文章的第三篇,敬请关注系列文章:

  • 基础概念
  • 设计你的自动评估任务
  • 一些评估测试集
  • 技巧与提示

如果你感兴趣的任务已经得到充分研究,很可能评估数据集已经存在了。

下面列出了一些近年来开发构建的评估数据集。需要注意的是:

  • 大部分数据集有些 “过时”,因为它们是在 LLM 出现之前构建的,当时是为了评估语言文本的某个特定属性 (如翻译、摘要),但是可能已经不适合现在的 LLM 评估方法了 (现在的评估方法倾向于通用、整体性)。
    (
    如果你有空余时间可以对下列数据集添加出版日期,会对本文非常有帮助!
    )
    (
    这部分后续也会更新包含大语言模型的评估
    )
  • 有些数据集可能受到污染,因为它们已经在网络上公开了很多年了。不过这并不意味着在你的任务中它们就毫无用处!

Pre-LLM 数据集

评估名称 任务类型 任务数据 任务内容 数据集 备注
DeepFix 编码任务、代码转换、代码修正 7K 由学生编写的带有错误的 C 程序 修正 C 程序 论文
MLSum 生成、多语言、摘要总结 1.5 百万篇新闻摘要与文章配对,取材自 Daily Mail、Le Monde、Süddeutsche Zeitung、El Pais、Moskovskij Komsomolets 和 Internet Haber (涵盖英语、法语、德语、西班牙语、俄语和土耳其语)。 总结文章 论文 Hugging Face Palm:以提示符为前缀,将文章截断至 2048 个标记
TransCoder 编码任务、代码转换 用 Python/Java/C++ 语言编写的 852 个并行函数 将一种语言翻译成另一种语言 论文 来自论文
WMT 多语言、翻译 来自 WMT 机器翻译会议的数据集 - 可用的数据集取决于年份 将一种语言翻译成另一种语言 会议
Replace the 2 digits by the conference year
Adversarial NLI 语言推理 10K 蕴涵数据集是通过人机协作的对抗性攻击生成的,旨在寻找迫使模型预测错误蕴涵标签的谓词 (该数据集使用了来自 StoryCloze、CommonCrawl、Wikipedia、开放注解国家语料库、WikiHow 和 GLUE 的上下文)。 预测蕴含关系 论文 数据
Github
R1 至 R3 = 数据生成的轮次
APPS 文生代码 10K 用自然语言描述的 Python 编程问题,这些问题是从 LeetCode 网站抓取而来,并附带有一套测试用例。 解决 Python 问题 论文 Github
数据
AQuA 算术、论证 100K 选择题 (来源包括 GMAT、GRE 及其他资源),包含题目/选项/答案解析。 选择正确的多项选择题答案 (MCQA) 论文 Github 最佳结果是在添加了外部计算器后获得的
ARC 常识、论证 8K 小学科学问题:e = 简单题集,c = 挑战题集 选择正确的多项选择题答案 (MCQA) 论文 数据 注意,这是 AI2 论证 Challenge ,不是抽象与论证语料库。
ASDiv 分析推理、算术、论证 2.3K 数学世界小学问题,收集自各个网站,由一位硕士研究生标注答案和难度级别 (可能是高质量的) 解决问题 论文 Github
bAbI 论证 20 项任务,每项包含 2K 自动生成的问题 + 短场景 (通过模拟的文字冒险游戏生成的连续动作)。 对句子进行推理以选择正确的结论 论文 Github
数据
参见第 4 部分以了解模拟环境及其约束,这是一个相当有趣的想法。对于其他类型的推理,可能不会太难重现。
BBQ 偏差检测 58K 示例,每个示例包含两种情境 (模糊情境和明确表现出偏见的情境) 、两个问题 (负面问题和非负面问题) 以及可能的答案。这些示例是根据手动模板构建的,并通过众包方式进行检查。 预测正确且无偏的答案。根据上下文或问题的不同,准确率之间的差异可以构建一个偏见分数。 论文 Github
BLiMP 语言理解 67 个数据集,每个数据集包含人工生成的 1K 最小对,用于测试句法、形态学和语义知识,这些数据集通过 MTurk 平台进行了验证。 通过检查模型分配给正确句子的对数概率是否更高来衡量准确性。 论文 Github 测试的内容包括:回指一致性、论元结构、绑定、控制/提升、冠词-名词一致性、省略、填充语-空位、不规则形式、孤岛效应、NPI 许可、量化词、主谓一致
BOLD 生成、有害内容检测 从包含种族/宗教/政治/性别/职业群体成员的维基百科句子开头提取的 23K 提示 (例如:女性艺术家,对应性别=女性)。 任务: 生成句子结尾,毒性通过一系列指标进行评估 (情感分析、使用分类器等)。在 HELM 中,毒性是通过 Perspective API 进行测量的。 论文 Github
BooksCorpus N/A 从网络上抓取的 11K 未出版书籍,每本书超过 20K 单词 (涵盖 16 种不同体裁)。 在原始论文中,它被用于训练一个句子嵌入模型 — 在模型论文中,它常常被用于污染或困惑度评估。 论文 Hugging Face
BooksCorpus_HELM 生成、记忆 来自 BooksCorpus 的 1K 随机抽样书籍。 任务: 从一段文本的随机数量的标记开始,模型必须生成后续内容 — 测量精确和近乎精确的再现。 论文 数据
BoolQ 语言推理、语言理解 来自 Wikipedia 的 16K 自然发生的是/否问答句子,来源于问题 + 上下文。 回答多项选择题 (MCQA) 论文 网站
CB 语言理解 1.2K 的语篇 (来自《华尔街日报》的新闻、来自 《英国国家语料库》的小说、来自《Switchboard》的对话),包含上下文 + 目标句子。 预测承诺蕴含 论文 网站
Civil comments 有害内容检测 1.8M 在线评论,伴有根据 Perspective API 指南通过众包形式获得的人工标签以标注毒性和身份术语,在这些评论中,450 K 附有身份术语标签 (众包,从列表中选择)。 任务: 毒性预测,标签用于识别模型中的偏差区域。 论文 Kaggle
Hugging Face
原始论文包含了一个合成测试集 (77K 示例是从使用50个身份术语的模板生成的,毒性内容的比例为50/50) 和一个人工标注的数据集 (描述在任务内容栏中) —— 我认为可用的数据集是后者。
Clean E2E NLG 描述、生成 50K 通过众包生成的餐厅描述,给定关键词和值 (食物类型 = X,预算 = Y……)。 论文 Hugging Face Palm: 在提示符前缀下,将文章截断至2048个标记。
CNN/DailyMail 完形填空、总结 原始数据集:200 K 新文档 (CNN/ Daily Mail 在 2007 年到 2015 年间) 被转换为完形填空格式,通过移除一些文本中的命名实体,并将它们用作关键词。 在 HELM 中: 使用上述文档 (以完整形式) 作为文本进行总结,并使用其重点作为黄金摘要。 论文 Hugging Face
数据
(我怀疑这并不能产生非常好的摘要)
CommonsenseQA 常识、论证 12K 众包的问答对 (基于 ConceptNet 关联初始化),然后通过质量进行过滤,并从 Google 搜索查询中添加了上下文 > 部分文本可能与 CC 数据重叠 回答多项选择题 (MCQA) 论文 最佳结果是在添加了外部计算器的情况下获得的
Contrast Sets 生成、健壮性 10 组对比集,每组最多 1 K 示例,用于他们的数据集 (详见评论),这些是由研究人员 (通常是原始论文的作者) 制作的 (增加问题中的推理步骤,用反义词替换词语,改变数量等)。 遵循原始任务设置并使用新示例,观察性能是否下降 。
在 HELM 中: 使用 IMDb 和 DROP 对比集。
论文 数据 NLVR2、IMDb 情感分析、MATRES 时间关系识别、英文 UD 解析、PERSPECTRUM、DROP、Quoref、ROPES、BoolQ、MC-TACO 。
COPA 常识、语言理解 1K 前提 + 因果问题 (附带选项,常识性问题) 论文 网站
CoQA 上下文阅读理解 127K 对话式问答,基于给定的上下文 (必须同时提供理由)——由标注者撰写 论文 v1.0 from
数据
DataImputation 现实任务、论证、结构化的数据 8 个来自多个来源的结构化数据集。 任务: 从一组带有空缺的属性中,模型必须填充这些空缺 (例如: 从电话号码推断城市,从规格推断电话品牌)。 论文 Data restaurant
Data Buy
参见表 2 获取所有数据源。

在 HELM 中:使用子集 Buy 和 Restaurant,将输入转换为自然语言,测试准确性。
Digits arithmetics (2D+, 2D-, 3D+, 3D-, …) 算术 基本的 n 位数算术任务,包括加法、减法、复合运算,每种运算各有 2K 个示例。 任务:解决数学问题 论文 Github 所有链接均来自 lm-evaluation-harness/lm_eval/datasets/arithmetic
DROP 算术、上下文阅读理解 55K 对抗性问题,这些问题需要 1) 从文本中选择相关项目,并且 2) 对这些项目进行计算 (排序/计数/……) 以获得正确答案。 任务:选择并计数以提供正确的答案 论文 数据
Dyck language_HELM 符号处理 500 个 D_n 单词,长度在 52 到 100 个字符之间 (“单词”由嵌套的括号组成),其中最后 i 个字符已被移除。 任务:预测唯一的闭合括号序列。 论文 Github
Also has a different version in BigBench
GSM8K 分析推理、论证 8.5K 各类小学数学问题 论文 Github
Hugging Face
最佳结果是在添加了外部计算器的情况下获得的
HellaSwag 完形填空 60K 对抗性过滤的多项选择题问答 选择正确的下一个句子 (来自字幕或 WikiHow)。 论文 Github
HumanEval 编码任务、文生代码 164 手写编程问题,包含函数签名、文档字符串、函数体 + 单元测试 目标是完成函数以通过单元测试。 论文 Hugging Face
IMDB 情感分析 50K 条来自 IMDB 的评论,其中正面评价 (评分 ≥ 7) 与负面评价 (评分 ≤ 4) 均衡分布 (不含中立评价)。 分类正面/负面评论。 论文 网站
LAMBADA 完形填空 10K 叙事上下文 (来自 BookCorpus),随后是一个句子,其中最后一个词被遮掩且必须被预测。特别构建以强制使用上下文。 预测最后一个词。 论文 Zenodo
Language Modeling Evaluation_HELM 语言模型 在 HELM 中编译了多个数据集:WikiText-103、ThePile (特别是 arXiv、BooksCorpus2、Enron Emails、PubMed Central、Wikipedia)、TwitterAAE、ICE。 任务:获取完整序列的条件对数概率 (困惑度测量)。 论文 The pile website
BLIMP Github
Wikitext data
Twitter AAE data
ICE data
LegalSupport 蕴含, 现实任务、论证 20K 个法律蕴含情景,构建于州/联邦法律意见之上 (断言用作上下文,并随机选取 2 个支持来源 ("参见 X,规则"))。 任务:确定哪条规则最支持该断言。 论文 数据
LinuxKernel_HELM 生成、记忆 2K 个从 Linux 内核中随机抽取的函数。 任务:从函数起始的随机行数出发,模型必须生成后续内容——衡量精确和近乎精确的再现。 论文 数据
LSAT 分析推理、上下文阅读理解、逻辑推理 10K 个来自法学院入学考试 (分析、逻辑推理和阅读理解) 的问题,包含上下文。 回答多项选择题 (MCQA) correctly 论文 Github
Magellan Benchmark 现实任务、论证、结构化的数据 23 个来自多个来源的数据集,包含具有属性的实体。脏数据集包含故意制造的错误,例如属性位于错误的列中、拼写错误等。 任务:给定来自两个不同表的两个实体,确定它们是否相同。 论文 Github 很可能 Abt-Buy 和 Buy 是相同的数据集。
MATH (Mathematics Aptitude Test of Heuristics) 分析推理、逻辑推理、论证、符号处理 12.5K 来自真实比赛的数学问题,以自然语言和 LaTeX 格式呈现。 论文 数据 HELM: 使用一个 "use_chain_of_thought" 标志位。
MAWPS 算术、论证 3.3K 数学应用题 (问题 + 答案 + 模板,来源于现有数据集:AddSub、SingleOp、MultiArith、SingleEq、SimulEq-S 和 SimulEq-L) 解决数学问题 论文 Github 最佳结果是在添加了外部计算器的情况下获得。
MBPP 编码任务、文生代码 1K 入门级 Python 群体众包编程问题 (描述,解决方案,3 个单元测试用例) - (58 % 数学相关,43% 列表处理,19% 字符串处理,9% 整数序列,以及 2% 其他)。 解决 Python 编程问题 论文 Github
Hugging Face
还包含一个编辑版本 (400 项),具有明确的提示和良好的签名 (之后可以查看以了解提示对代码生成的影响) + 一个 MathQA - Python 数据集 (MathQA 数据集的改编版本)
MMLU 语言理解 15K 多选题问答 是从各种在线资源手动收集的,涵盖多个主题 (法律、哲学、经济学、心理学、STEM、医学等, - 从高中到专业水平)。 回答多项选择题 (MCQA) 论文 Hugging Face
Github
看起来像是一个强大/高质量的基准线
MRF (Misinfo Reaction Frames) 生成、虚假信息生成能力 200 K 条新闻标题中的声明配对 (气候变化、COVID-19、癌症疾病,详细来源见评论) + 标签 (真实/虚假信息),前者由 MTurk 工人标注了真实性、传播可能性、作者意图。 任务:必须预测黄金标签或生成可能的作者意图、读者感知等…… 论文 Github (包含来自 NELA-GT-2018-2020, SciDCC, Climate-FEVER, CoAID, CoronaVirusFacts/DatosCoronaVirusAlliance 数据库, ESOC Covid-19 错误信息数据集, DETERRENT 的数据)
MS MARCO 问答、检索 100 万条匿名化的问题,配有自由格式的人工生成答案 (来自相关网页文档摘录),其中一些问题还添加了改写版本。 原始论文包含 3 个任务:1) 尽可能生成正确的答案,2) 同上但答案即使在没有上下文的情况下也应该合理,3) 对 1000 个段落按照与问题的相关性进行排序。 论文 Github 包含对 QA 数据集在文献综述中的扩展描述 。
在 HELM 中,仅考察排序任务,并且通过查看在询问“段落是否回答了查询?”时预测的对数似然性来估计相关性。
MS MARCO TREC, aka TREC 2019 检索 源自 MS MARCO 的数据集,编辑用于段落或文档检索任务,执行完整检索或顶级-n 重排序 (文档为 100,段落为 1000)。(参见 MS MARCO) 论文 数据
Github
MultiRC 语言理解、问答 6K 多选题涵盖多种主题 论文 数据
NarrativeQA 问答、检索 47K 自由形式的人工生成问题和答案,关联到 1.5K 书籍 (Gutenberg 项目) 和电影剧本 (抓取),并与情节概要相匹配。 任务:根据摘要或故事,回答或选择正确答案。 论文 Github 对于长距离上下文测试,我们可以使用这个数据集从完整的故事中进行问答。对于任何对话系统而言,这可能都很有趣。
Natural Questions 开放域/闭书任务、问答 207K 汇总的 Google 搜索查询 + 标注的 Wikipedia 示例答案 论文 数据
NewsQA 问答 100K 人工生成的问答对来自 12K 新闻文章 (CNN)。问题是从标题 + 摘要生成的,答案是从问题 + 文章中得出的,然后通过验证机制保留 。
可能与 CNN / Daily Mail 有交集,因为数据提取脚本是相同的。
论文 Github
OpenBookQA 常识、论证 6K 句子,需要运用常识知识进行科学推理,以将结论外推到新情况。 论文 数据
PIQA 常识、论证 20K 物理常识推理情境 从上下文中选择正确的操作并作答 论文 数据
PopularBooksCorpus_HELM 生成、记忆 来自 BooksCorpus 的 20 本书,这些书出现在畅销书列表中。 任务:从构成书籍第一个段落的随机数量的标记开始,模型必须生成后续内容——衡量精确和近乎精确的再现。 论文 数据
QuAC 上下文阅读理解 100K 个信息寻求型 QA (问答) 情境中的问题 (使用 Wikipedia 来生成数据集) 论文 数据
RACE 上下文阅读理解 100K 个来自中国中学生/高中生英语阅读理解考试的问题 论文 数据
RAFT 现实任务、文本分类 11 个自然发生的分类任务数据集的汇编,测试项目数量在 150 到 5 K 之间。 任务:在少量样本中,从 50 个标注示例出发,提供有意义的标签。(领域:医疗、金融、研究、英语语言、法律、物理、人工智能安全、社交网络) 论文 Hugging Face 语料库: (ADE 语料库 v2、Banking77、NeurIPS 2020 影响声明风险、OneStopEnglish、Overrruling、系统评价纳入、TAI 安全研究、服务条款、TweetEval 恶意内容、Twitter 投诉、半导体组织类型)
RealToxicityPrompts 生成、有害内容检测 100K 自然发生的句子 (从 OpenWebText 语料库中选取,基本上等同于 Reddit,并使用 PerspectiveAPI 对毒性进行评分) 被分成两部分,以创建提示和延续。 任务:从句子开头生成续写内容,然后使用 Perspective API 对生成内容的毒性进行评估。 论文 数据
Github
(the repo lacks a lot of info)
ReCoRD 语言理解 120K 段落/完形填空的查询/答案 示例 来自新闻 (CNN、DailyMail),并经过人工筛选 论文 数据
RTE 语言理解 3K 竞赛数据汇编 关于蕴含关系 论文 数据
SAT analogies 语言理解 374 个 2005 年之前的 SAT 类比问题 (a 与 b 的关系如同 c 与多项选择题的关系;词语不是最常见的) 论文 Data dev
Data test
SIQA 问答
SQuADv2 上下文阅读理解 结合了 SQuAD 与 50K 不可回答的问题 根据上下文给出答案,但仅在可能的情况下。 论文 Github
StoryCloze 完形填空、常识 50K 五句话的常识故事 选择正确的结尾 论文 Hugging Face
StrategyQA 常识、论证 2.8K 需要从隐性知识进行推理的问题 论文 最佳结果需添加外部计算器
SVAMP 算术、论证 1K 数学应用题 (采样自 ASDivA,质量高于 MAWPS),具有不同的表述变化 论文 Github 最佳结果需添加外部计算器
Synthetic reasoning (natural) 逻辑推理、论证 即时生成的合成数据,包含一组合成规则 (条件语句)、事实 (属性) 以及逻辑上的标准输出。 论文 Can be generated with
Github
也被称为 HELM 中的 rule_induct
Synthetic reasoning (symbolic)_HELM 逻辑推理、符号处理 使用模式模板即时生成的合成数据。 要么测试模型是否能够识别模式(例如“beach + beach - pear”具有“A + A - B”的模式),要么测试模型是否能够在给定的模式中替换字符串。 论文 Can be generated with
Github
TriviaQA 开放域/闭书任务、问答 95K 杂学问答 (组合型问题,语法变异性) 论文 数据
TruthfulQA 问答 817 个关于复杂事实主张的问题 (常见误解、错误等),涵盖 38 个类别,附带真和假的参考答案 + 支持真实答案的来源 (以及额外增加的 380 个问题)。 论文 Github
TyDiQA-GoldP 多语言、问答 204K 多语言 QA 对 (从提示中不限制地引出问题,然后检索维基百科文章,并在文章中选择特定答案 (如果可能的话)) (语言包括:英语、阿拉伯语、孟加拉语、芬兰语、印度尼西亚语、日语、韩语、俄语、泰卢固语、泰语和斯瓦希里语)。 MCQA 论文 Github 生成的数据集可以展示有趣的问题、目标不清楚的问题和问题与答案语言水平之间的不匹配。可能比其他数据集更具挑战性。
Web Questions 开放域/闭书任务、问答 从 Google Search API 中提取了 100K 个 “Wh?” 类型的问题,然后由 MTurkers 进行标注 - 我怀疑部分答案可能已经过时。 MCQA 论文 网站
WebNLG 生成、言语化 13K 个三元组 (主题, 属性, 客体) 与句子表述之间的映射关系,这些三元组是从 DBPedia 构建的,而 DBPedia 是源自 Wikipedia 的知识库;句子表述是由众包工人完成的,涉及特定主题 (宇航员、大学、纪念碑、建筑物、漫画角色、食品、机场、运动队、文学作品)。 任务:以语法正确的方式表达。 论文 Hugging Face 有一项关于流畅性的句子选择,生成的句子相对简单,但没有描述注释者/众包者的来源 > 可能部分数据不是“标准英语”。
WiC 语言理解 7K 数据,判断一个词在两个不同语境中出现时是否具有相同含义的分类。 论文 Site
WikiFact_HELM 完形填空 12 个领域,每个领域包含 1K 三元组 (主题,关系,对象),这些三元组采样自 Wikipedia 并经过清理。 任务:预测由关系构成的句子中缺失的项目。 论文 Codalab
Github
WikiLingua 生成、多语言、总结 43K 文章 / 摘要对由 WikiHow 构建,涵盖 18 种语言 (在网站上,文章是以每个步骤一个总结句 + 详细段落的形式书写的:在数据集中,摘要为总结句的连接,而文章则是详细段落的组合)。 总结 论文 Github Palm: 以提示符为前缀,将文章截断至2048个标记
我怀疑数据创建可能导致总结基线的语言非常“机械化”,这可能会突出更流畅的总结 (尽管 ROUGE 对此不应该过于敏感)。
Winogender 偏差检测
Winograd 论证、温格拉德模式 273 至 285 个例子,其中必须消除歧义以确定代词指的是谁或什么,这些句子是特意构造的,在统计上是模糊的,但对人类来说不是。 代词的消歧 论文 网站 不确定 GPT3 是否在这个数据集或 SuperGLUE 数据集上进行了评估。
WinoGrande 论证、温格拉德模式 43K 句子 对抗性 Winograd 论文 网站
WSC 语言理解、温格拉德模式 Winograd 模式挑战 (见 Winograd) 论文 网站
XSUM 总结 226K 篇新闻文章 (BBC,2010 年至 2017 年) 与其单句摘要相匹配 (摘自文章)。任务:概括总结。领域:新闻、政治、体育、天气、商业、科技、科学、健康、家庭、教育、娱乐和艺术。 论文 Github
XSum 生成、总结 226K 篇来自 BBC (2010 - 2017 年) 的新闻摘要/文章对,从 WayBack 机器中提取。 论文 Hugging Face 可以手动检查最近的知识是否导致了旧新闻摘要中的差异,这可能会很有趣。

可手动重现的数据集想法

评估名称 任务类型 任务内容 数据集 备注
✍️ GSM8K-Python 编码任务、文生代码 GSM8K 数据集的 Python 版本 (8.5K 小学数学问题) 论文 N/A
✍️ MRF 生成、人工评估、虚假信息生成能力 从MRF 数据集抽取了 250 个标题,并依据论点将其分组为 80 个簇。任务要求:基于每个论点及其对应的 5 个标题,模型需要生成能够支持该论点的合理标题。评估人员将对生成的标题进行评价,判断其是否 1) 支持论点,以及 2) 看起来真实可信。 论文 数据 参见
报告
第 6 页获取关于原始过程的更多说明,以及 HEMLM 论文的章节 8.5.2、E.5 和 5.5。
✍️ News article generation 生成 根据标题和副标题生成了 25 篇文章,80 名人类评估者需要判断这些文章是生成的还是原始的。 论文
✍️ Numeracy Prediction 符号处理 要求模型根据给定的几个例子执行符号回归,并将数字关系应用于新的输入。 论文 Github
✍️ SVG datasets 可构造一个 SVG 数据集,用于检查模型是否确实能够生成或者分解 SVG 图形 Twitter 会话
✍️ Theory of the mind datasets 可能很容易生成 论文
✍️ Wedging prompts 生成, 人工评估、虚假信息生成能力 具有特定意图的 11 个提示 (例如:影响投票行为,通过生成支持/反对 X 的言论来针对特定群体),并附有 3 个示例。任务:生成后续示例。 论文 数据 在 HELM 中:使用人工评估来确定生成的消息 1) 是否针对特定群体;2) 是否支持预期的信息;3) 是否具有分裂性。
✍️ Word scrambling 符号处理 10,000 个示例,涵盖 5 项字符操作任务 (字母循环移位的单词、字母重组、随机插入、反转)。模型需要恢复原始单词。 论文 易于生成/自动化,参见 GPT3 论文的第 3.9.2 节。


英文原文:
https://github.com/huggingface/evaluation-guidebook/blob/main/translations/zh/contents/automated-benchmarks/some-evaluation-datasets.md

原文作者: clefourrier

译者: SuSung-boy

审校: adeenayakup

02 简单的增删查改

前情提要:承接了01中的
engine
以及
User

2-1 了解会话机制

  1. 个人理解

    在SQLAlchemy 增删查改中是依赖会话(Session)这个机制进行操作的,我个人的理解是用“会话“进行连接数据库周期的一系列管理操作(以下是ai生成对此会话的理解)

  2. ai理解

    在 SQLAlchemy 中,
    sessionmaker
    是用于创建
    会话(Session)
    对象的工厂类,负责与数据库的交互。会话(Session)是 SQLAlchemy ORM 的核心部分,它管理与数据库的连接,并在一次操作中追踪对象的状态变化(如添加、修改、删除),同时处理事务的提交和回滚。

    会话(Session)的作用


    1. 管理事务
      :会话负责开始、提交和回滚事务。通过会话,SQLAlchemy 可以在多个数据库操作间提供原子性(即要么全部成功,要么全部失败)。
    2. 对象的持久化
      :会话在内存中追踪对象的状态变化,确保对象在数据库中得到正确的插入、更新或删除。
    3. 查询管理
      :会话管理 SQL 查询的生命周期,包括从数据库获取数据,执行查询语句等。

2-2 创建会话

  • 流程:


    1. 导入对应包,依赖其中的
      sessionmaker
    2. 使用
      sessionmaker
      生成新的会话对象
      Session
      ,生成时绑定之前创建过的引擎
    3. 通过
      Session
      对象我们来构造对应的实例【可能有点绕,但一开始2调用的只是我们绑定好的类,我们还需要对这个对象创造实例来进行会话管理操作】
  • 官方的用例参考,他用的数据库类型不一样,但是思路是一样的:

    eg1:

    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    
    # an Engine, which the Session will use for connection
    # resources
    engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/")
    
    Session = sessionmaker(engine)
    
    with Session() as session:
        session.add(some_object)
        session.add(some_other_object)
        session.commit()
    

    eg2
    :这个就是后文使用的创建实例进行操作了

    session = Session()
    try:
        session.add(some_object)
        session.add(some_other_object)
        session.commit()
    finally:
        session.close()
    

    eg3

    Session = sessionmaker(engine)
    
    with Session.begin() as session:
        session.add(some_object)
        session.add(some_other_object)
    # commits transaction, closes session
    
  • 看完官方的实例,来写我们自己的会话管理了:


    1. 简化版:

    from test_package_sql import engine, User #这个只是导入01文件提及的engine和User类,名字自己改一下
    from sqlalchemy.orm import sessionmaker
    
    Session = sessionmaker(bind=engine)#先通过时间创造器绑定引擎->创建这个会话类
    
    session = Session()#根据我们自己的Session类创建属于我们自己的实例对象用于后续操作
    

    1. 详细版:

      from sqlalchemy import create_engine, Column, Integer, Float, String
      from sqlalchemy.orm import declarative_base
      
      from sqlalchemy.orm import sessionmaker
      
      local_url = "sqlite:///02_test.db"
      engine = create_engine(url=local_url)
      local_base = declarative_base()
      class User(local_base):
          __tablename__ = "User"
          id = Column(Integer, primary_key=True)
          name = Column(String)
          age = Column(Integer)
      
      local_base.metadata.create_all(engine)
      

2-3 增

  1. 事前bb【觉得烦的可以略过】

    在进行增删查改前,必须再强调一下这个会话机制的流程:
    创建会话->进行管理操作(包括但不不限于增删查改)->提交会话管理
    【注意,提交时的更改的只是当前会话状态,言下之意,你提交了一次再修改,没提交那还是之前提交的状态】

  2. 流程介绍【增加单个
    User对象


    • 创建需要增添的实例——
      必须与User类相匹配
      ,就是说是User类对象

    • 使用对话机制的
      session.add
      接口进行添加

    • 添加若干个后,结束则使用
      session.commit()
      进行修改后的提交

      主函数直接调用就好,我这样子写好封装,看得也清楚,很简单对吧


    def add_one():
        User1 = User(name="arthur",age=18)
        User2 = User(name="lihua",age=21)
        session.add(User1)
        session.add(User2)
        session.commit()
    

    • 增添效果如下【db为空时】:

      image-20250108000748412

      下一集我再对如何显示数据库做一个解释吧,毕竟是从零开始(bushi)

  3. 增添多个对象【或者是User_list】

    只需要修改接口以及传入参数就好了,使用
    session.add_all()
    接口

    def add_Users():
        User1 = User(name="arthur", age=18)
        User2 = User(name="lihua", age=21)
        Users = [User1,User2]
        session.add_all(Users)
        session.commit()
    

    • explain:Users就是User 类(项目)的可迭代对象(列表),让我们看看官方对于这个接口的解释:

    method
    sqlalchemy.orm.Session.
    add_all
    (
    instances: Iterable[object]
    ) → None

    Add the given collection of instances to this
    Session
    .

    添加实例到Seesion会话中。这句话可能不太好理解,看看他的传参解释其实就很直观,其实就是传入可迭代对象XD


    • output:

      image-20250108001929442

      就结束了,其实增删改查不难,接口已经抽象出来了,记住逻辑就好

2-4 查

还是得先说查啊,不然没法删啊0v0

  1. 接口介绍

    q = session.query(SomeMappedClass)


    • 参数介绍:

      SomeMappedClass
      :所映射的类

      q
      :返回的类型是
      Query[Any]
      ,即任何满足要求的数据

    • 常用后缀


      1. .all()
        :以列表的形式传回搜索的结果

      session.query(User).all()#用来返回User表的所有数据
      

      1. sqlalchemy.orm.Query.
        filter_by
        (* *kwargs)

        这个是常用的简化版的搜索接口。
        !注意他可以同时接收多个变量,且只使用等值过滤条件

        results = session.query(User).filter_by(ag,e=21)
        results = session.query(User).filter_by(age=21,name="lihua")
        
      2. session.query(Model).filter(condition)

        运行使用多个复杂的表达式,支持更多条件类型,
        支持手动连接多个条件
        :如果需要多个条件,可以使用
        AND

        OR
        手动连接条件。但就说注意对比时需要
        User.xxx
        --你自己定义的类表

        results = session.query(User).filter(User.name == 'arthur')#不止支持== ,还支持其他比较运算符
        
      3. .one_or_none()

        用于查找
        是否只有一个
        或者
        none个
        ,找到多个则会报错


    1. 编码

      其实把上面的看懂了就已经学会了如何搜索了


      • 简单搜索法:

        def search():
            results = session.query(User).filter_by(age=21)
            for result_one in results:
                print(result_one)
        

        image-20250108150708363

      • 使用传统接口更多扩展的的搜索:

        def other_way_search():
            results = session.query(User).filter(User.name == 'arthur')
            for result_one in results:
                print(result_one)
        

2-5 删

  • 删除主要运用到
    session.delete(object)
    接口,主要有以下两种用法:
  1. 删除单个对象:
session.delete(object)#object是单个对象
session.commit()
  1. 删除多个满足条件的对象

    session.query(Model).filter(condition).delete()
    session.commit()
    

    流程大概是:
    找到想要删除的对象->删除->提交

  • code:

    def remove_one():#单个
        results = session.query(User).filter_by(age=21).first()#找到第一个
        session.delete(results)
        session.commit()
    

    原数据库:

    image-20250108151915387

    删除后:

    image-20250108151952755

    def remove_all():#多个
        results = session.query(User).filter_by(name='arthur').delete()
        session.commit()
    

    删除后:

    image-20250108152247865

  • 删除尾声:

    删除就结束了,最后各位可以尝试把lihua也删除,然后根据上面的教程添加再添加4个User信息,其中要有两个age、name不一样

    参考code:

    def add_4new_user():
        User1 = User(name='arthur', age=18)
        User2 = User(name='Abigail Williams',age=14)
        User3 = User(name='caster', age=21)
        User4 = User(name='Lilith', age=22)
        users = [User1,User2,User3,User4]
        session.add_all(users)
        session.commit()
    

    结果:

    image-20250108153103874

2-6 改

改其实最简单,找到对应的
object
然后修改,提交即可,非常朴实无华

def update_f():
    caster = session.query(User).filter_by(name="caster").one_or_none()#找到一个caster的信息
    caster.age = 18			#修改就好啦
    session.commit()		#记得提交

image-20250108153851400

part2结束,感谢观看,读者可以自行实践一下增删查改,最好融合起来一起实践

可能您还没有听说过,GitHub 刚刚宣布了 Copilot Free(免费版)!好消息是:您现在已经可以在 Visual Studio 中开始使用 Copilot Free 了。它现在已经可用了,我们将在1月份对更精简的体验进行最后的润色。

我们很高兴能为整个 Visual Studio 家族带来这些好处。有了 Copilot Free,您将拥有人工智能驱动的工具,就在您的指尖——更智能的调试,人工智能生成的提交消息,人工智能断点放置,当然还有代码补全,聊天等等。开发人员已经看到 Copilot 的速度提高了25%,现在您可以在 Visual Studio 中亲身体验这种提升。

准备好尝试一下了吗?

https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2Fsettings%2Fcopilot

一些建议

1. 现在就试试吧:不要犹豫或者仅仅是等待。今天就在 Visual Studio 中试用 GitHub Copilot Free 吧。请注意,目前,当您达到使用限制时,您不会收到通知,但我们会在1月份为您提供更新。

2. 保持更新:让您的 Visual Studio 安装保持最新状态并订阅预览频道。通过保持在最前沿,您将成为第一个享受最新更新的人,确保您在我们推出新功能时充分利用 Copilot Free。

展望一月

在 Visual Studio 中使用 Copilot Free 会更容易。当您达到使用限制时,您将看到清晰的指标——不再需要猜测。如果您发现自己需要更多,升级到无限制计划将是平滑和无缝的,这样就能让您的想法源源不断。

请关注这些更新的最新预览,不要忘记通过开发者社区分享您的反馈!

原文连接:https://devblogs.microsoft.com/visualstudio/github-copilot-free-is-here-in-visual-studio/

前言
本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发。
iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动。
本合集是基于新版本的关于分部件(widget)的使用介绍,包括源代码介绍、实例使用等。

环境配置
系统:window10
平台:visual studio code
语言:rust
库:iced 0.13

iced布局简介

iced中用于布局的部件有column、row等,我们在之前的博文里的示例代码中,就使用了column布局,也就是纵向排列的布局。同样,顾名思义,row即是横向布局。
二者可以嵌套使用,形成纵、横布局。

1、column布局

在iced中的定义就是:

//! Distribute content vertically.

创建一个column布局有几种方式,在我们前文的示例中,使用了column!这样的方式,这是一个快捷的方式,属于iced官方定义的一个宏macro:

官方源码
#[macro_export]
macro_rules! column {
    () => (
        $crate::Column::new()
    );
    ($($x:expr),+ $(,)?) => (
        $crate::Column::with_children([$($crate::core::Element::from($x)),+])
    );
}

这个宏可以直接创建一个Column实例,也可以根据传入的子项来创建Column实例。
以前文代码为例:

column![
            button("增加Inc").on_press(Message::Inc),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec)
        ]

此处,我们创建了一个column,并在其中添加了两个按钮和一个text,它们将在窗口呈纵向排列,我们可以通过设置column的spacing属性来调整其中元素之间的间隙。
image
将spacing设置为10:
image

我们可以来看一下Column的官方结构体定义:

官方源码
pub struct Column<'a, Message, Theme = crate::Theme, Renderer = crate::Renderer>
{
    spacing: f32,
    padding: Padding,
    width: Length,
    height: Length,
    max_width: f32,
    align: Alignment,
    clip: bool,
    children: Vec<Element<'a, Message, Theme, Renderer>>,
}

可以看到,其参数中,大部分是属性设置,其中children用于设置传入的子元素,也就是你希望在当前窗口某部分程序纵向排列的子元素,可以是任何widget,也可以嵌套布局,如column、row。
比如,我们将前文的按钮、文本的布局设为row,然后再嵌入到column中:

let row1=row![
            button("增加Inc").on_press(Message::Inc),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec)
        ].spacing(10).padding(20);
        column![
           row1,
        ].spacing(10).padding(20)
        .align_x(iced::Center)
        .into()

看下效果:
image
我们多增加一些部件和嵌套:

let row1=row![
            button("增加Inc").on_press(Message::Inc).width(60),
            text(self.count).size(20),
            button("减少Dec").on_press(Message::Dec).width(60)
        ].spacing(10).padding(20).width(200).height(100);
        let col1=column![
            button("col1").width(60).on_press(Message::None),
            text("col1").size(12),
            button("col1").width(60).on_press(Message::None),
        ].spacing(10).padding(5);
        
        let color1=iced::Color::from_rgba(155.0,0.0,0.0,255.0);
        let cont_row=container(col1)
                                        .style(move |t|styles::mycontainerstyle(t,color1))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let col2=column![
            text("col2").size(12),
        ];
        let color2=iced::Color::from_rgba(0.0,155.0,0.0,255.0);
        let cont_row2=container(col2)
                                        .style(move |t|styles::mycontainerstyle(t,color2))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let col3=column![
            text("col3").size(12),
        ];
        let color3=iced::Color::from_rgba(0.0,0.0,155.0,255.0);
        let cont_row3=container(col3)
                                        .style(move |t|styles::mycontainerstyle(t,color3))
                                        .width(100).height(200)
                                        .align_x(iced::Center).align_y(iced::Center);
        let row_col=row![
            cont_row,cont_row2,cont_row3
        ].spacing(10).padding(20).height(200);
        column![
           row1,
           row_col,
        ].spacing(10).padding(20)
        .align_x(iced::Center)
        .into()

仔细看一下上面的代码,我们在原先的基础上,添加嵌套布局,总体布局是纵向,纵向有两层,第一层是原先的部件,第二层我们又嵌套了横向布局,一共三列,每一列又嵌套了纵向,为了显示区别,我们添加了背景色,其中关于style的使用,本文不做赘述。
看一下效果:
image
注意图片中的红黄蓝区域,此处我使用了container部件,方便设置背景色,以作区别。
当然,上面的布局看起来可能不是很整齐,但是实现的效果是对的,即column和row的嵌套来实现页面的布局,可以通过设置spacing和padding来微调部件的位置。
下面,我调整一下代码,为了使布局看起来更简洁有效,我们将显示一个按钮九宫格布局,那么就是三列或者三行互相嵌套,而且其中的子元素都是按钮,且居中排布。
先修改一下代码:

let col1=column![
            button(text("col1_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col1_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col1_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        
        // let color1=iced::Color::from_rgba(155.0,0.0,0.0,255.0);
        // let cont_row=container(col1)
        //                                 .style(move |t|styles::mycontainerstyle(t,color1))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let col2=column![
            button(text("col2_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col2_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col2_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        // let color2=iced::Color::from_rgba(0.0,155.0,0.0,255.0);
        // let cont_row2=container(col2)
        //                                 .style(move |t|styles::mycontainerstyle(t,color2))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let col3=column![
            button(text("col3_1").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col3_2").size(15)).width(80).height(40).on_press(Message::None),
            button(text("col3_3").size(15)).width(80).height(40).on_press(Message::None),
        ].spacing(10);
        // let color3=iced::Color::from_rgba(0.0,0.0,155.0,255.0);
        // let cont_row3=container(col3)
        //                                 .style(move |t|styles::mycontainerstyle(t,color3))
        //                                 .width(100).height(200)
        //                                 .align_x(iced::Center).align_y(iced::Center);
        let row_col=row![
            col1,col2,col3
        ].spacing(10).padding(2).align_y(iced::Center);
        // column![
        //    //row1,
        //    row_col,
        // ].spacing(10).padding(20)
        // .width(300).height(300)
        // .align_x(iced::Center)
        // .into()
        let cont=container(row_col)
                                .align_x(iced::Center).align_y(iced::Center)
                                .width(300).height(300);
        cont.into()

上面的布局,有一些代码是之前的代码,但是被注释了,不用管它,我们只关注有效代码,修改后的代码显示的效果如下;
image

2、row布局

row布局与column布局是完全一样的,除了布局方向,所以就不再赘述了。

3、综述

column和row是iced中常见的布局,但是并不是唯一,iced还有其他可以实现布局的方式,但本文不再赘述,将在后续逐渐展开。
综合本文上述的介绍,哪怕只是使用column和row,经过调整之后,也是能做出比较好看的布局的,当然以上只涉及了布局,还没有仔细去设置样式,包括边框、颜色、阴影等这些样式,这些都将在后续博文中介绍。

前言

书接上文,prometheus已经安装好了,监控数据是有了,我们需要对其进行告警,并且可以发送到对应的平台,比如飞书、钉钉等,这里选择用飞书来测试

环境准备

组件 版本
操作系统 Ubuntu 22.04.4 LTS
docker 24.0.7
alertmanager v0.27.0

下载编排文件

本文所有的编排文件,
都在这里

▶ cd /tmp && git clone git@github.com:wilsonchai8/installations.git && cd installations/prometheus

安装alertmanager

alertmanager主要用作对prometheus发来的告警进行响应,包括发送、抑制等

▶ cd installations/prometheus
▶ kubectl apply -f alertmanager.yaml

检查是否启动

▶ kubectl -n prometheus get pod -owide | grep alertmanager
alertmanager-5b6d594f6c-2swpw        1/1     Running   0          69s   10.244.0.17    minikube       <none>           <none>

访问页面

▶ kubectl get node -owide
NAME       STATUS   ROLES           AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
minikube   Ready    control-plane   6d2h   v1.26.3   192.168.49.2   <none>        Ubuntu 20.04.5 LTS   6.8.0-45-generic   docker://23.0.2

▶ kubectl -n prometheus get svc | grep alertmanager
alertmanager         NodePort   10.110.182.95    <none>        9093:30297/TCP   70s

http://192.168.49.2:30297

测试alertmanager

1. 定义一个测试的deployment

▶ kubectl create deployment busybox-test --image=registry.cn-beijing.aliyuncs.com/wilsonchai/busybox:latest -- sleep 33333
deployment.apps/busybox-test created

▶ kubectl get pod
NAME                           READY   STATUS    RESTARTS   AGE
busybox-test-fcb69d5f9-tn8vx   1/1     Running   0          6s

2. 定义告警规则

我们定义当deployment的副本是为0就告警,修改prometheus configmap

在最底部追加,相当于新增一个配置文件,里面专门定义告警规则

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-cm
  labels:
    name: prometheus-cm
  namespace: prometheus
data:
  prometheus.yml: |-
    global:
      scrape_interval: 5s
      evaluation_interval: 5s

    alerting:
      alertmanagers:
        - static_configs:
            - targets: ['alertmanager:9093']

    rule_files:
      - /etc/prometheus/*.rules

    scrape_configs:
      - job_name: 'prometheus'
        static_configs:
        - targets: ['localhost:9090']

      - job_name: "prometheus-kube-state-metrics"
        static_configs:
          - targets: ["kube-state-metrics.kube-system:8080"]

      - job_name: 'kubernetes-nodes'
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
        kubernetes_sd_configs:
        - role: node
        relabel_configs:
        - source_labels: [__address__]
          regex: '(.*):10250'
          replacement: '${1}:9100'
          target_label: __address__
          action: replace
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)

# 从这里是新加的
  prometheus.rules: |-
    groups:
    - name: test alert
      rules:
      - alert: deployment replicas is 0
        expr: kube_deployment_spec_replicas == 0
        for: 30s
        labels:
          severity: slack
        annotations:
          summary: deployment replicas is 0

然后重启prometheus,查看告警是否生效

3. 触发告警

▶ kubectl scale --replicas=0 deploy busybox-test

等待些许片刻,查看alertmanager页面

已经有告警触发了

发送到飞书

我们已经有一个告警了,但是目前没法通知出来,需要给他告警到飞书去

1. 创建飞书的告警群组,并创建机器人拿到机器人的webhook

webhook:

https://open.feishu.cn/open-apis/bot/v2/hook/*******************

2. 创建发送消息的服务

这里我们选用python tornado web服务来接收从alertmanager发送的告警信息

from tornado.ioloop import IOLoop
import tornado.httpserver as httpserver
import tornado.web
import requests
import json

WEBHOOK_URL = 'https://open.feishu.cn/open-apis/bot/v2/hook/********'

def send_to_feishu(msg_raw):
    headers = { 'Content-Type': 'application/json' }
    for alert in msg_raw['alerts']:
        msg = '## 告警发生 ##\n'
        msg += '\n'
        msg += '告警:{}\n'.format(alert['labels']['alertname'])
        msg += '时间:{}\n'.format(alert['startsAt'])
        msg += '级别:{}\n'.format(alert['labels']['severity'])
        msg += '详情:\n'
        msg += '    deploy:{}\n'.format(alert['labels']['deployment'])
        msg += '    namespace:{}\n'.format(alert['labels']['namespace'])
        msg += '    content:{}\n'.format(alert['annotations']['summary'])
        data = {
            'msg_type': 'text',
            'content': {
                'text': msg
            }
        }
        res = requests.Session().post(url=WEBHOOK_URL, headers=headers, json=data)
        print(res.json())

class SendmsgFlow(tornado.web.RequestHandler):
    def post(self, *args, **kwargs):
        send_to_feishu(json.loads(self.request.body.decode('utf-8')))

def applications():
    urls = []
    urls.append([r'/sendmsg', SendmsgFlow])
    return tornado.web.Application(urls)

def main():
    app = applications()
    server = httpserver.HTTPServer(app)
    server.bind(10000, '0.0.0.0')
    server.start(1)
    IOLoop.current().start()

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt as e:
        IOLoop.current().stop()
    finally:
        IOLoop.current().close()

本脚本已上传至仓库

3. 修改alertmanager configmap

修改alertmanager的configmap,把webhook_configs改为sendmsg的api地址

apiVersion: v1
kind: ConfigMap
metadata:
  name: alertmanager-config
  namespace: prometheus
data:
  alertmanager.yml: |-
    global:
      resolve_timeout: 5m
    route:
      group_by: ['alertname', 'cluster']
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 5m
      receiver: default
    receivers:
    - name: 'default'
      webhook_configs:
        - url: 'http://127.0.0.1:10000/sendmsg'

重启alertmanager

4. 检查飞书

至此,一个简单告警流程制作完成

联系我

  • 联系我,做深入的交流


至此,本文结束
在下才疏学浅,有撒汤漏水的,请各位不吝赐教...