广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

栏目: IT技术 · 发布时间: 3年前

内容简介:摘要:本篇主要学习和分析BERT在美团搜索排序中的项目实践。首先介绍了业务背景,主要对比了美团搜索业务场景和我们的应用场景;然后讲了下计算query和doc相关性的方法,主要包括计算字面相关性和计算语义相关性,重点介绍了基于BERT的语义相关性内容;最后也是本篇的重点,分析了美团搜索排序项目实践以及对我们业务的思考,其中包括数据样本增强、BERT领域适配、模型轻量化、联合训练和排序服务架构优化等一系列眼花缭乱但是又极具工程价值的优化操作,对于我们有极大的工程借鉴价值。郑重声明,这篇文章主要是学习美团技术团队

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

摘要:本篇主要学习和分析BERT在美团搜索 排序 中的项目实践。首先介绍了业务背景,主要对比了美团搜索业务场景和我们的应用场景;然后讲了下计算query和doc相关性的方法,主要包括计算字面相关性和计算语义相关性,重点介绍了基于BERT的语义相关性内容;最后也是本篇的重点,分析了美团搜索排序项目实践以及对我们业务的思考,其中包括数据样本增强、BERT领域适配、模型轻量化、联合训练和排序服务架构优化等一系列眼花缭乱但是又极具工程价值的优化操作,对于我们有极大的工程借鉴价值。

郑重声明,这篇文章主要是学习美团技术团队发表的《BERT在美团搜索核心排序的探索和实践》这篇文章。总体看了不下五遍,属于精读的文章。小伙伴们可以直接去拜读原文,非常精彩。这里更多的是根据自己的思考和理解将原文整理成更容易理解的方式进行表达(至少对于我是更容易理解的方式),类似一种学习笔记的表现形式。很多小伙伴看到干货文章更多的是收藏+关注,然后就不了了之,成为“收藏党”。而我更推荐精读N遍,同时进行延伸查阅更多知识,最后以一种便于理解的方式整理出来,形成文章将知识固化。如果再能将固化的知识通过PPT等形式分享出来,那么理解的就更加深刻。

下面主要按照如下思维导图进行学习分享:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

01 背景介绍

最近在和搜索团队合作一些NLP相关的需求,总体来说主要分成以下两类任务:

  • query-tag:给用户搜索词打上标签,这里其实就是文本分类任务;

  • query-doc:给用户搜索词返回对应的搜索结果,这里其实是句子对关系任务。

本篇重点分析的就是query-doc类型的句子对关系任务。下面分别从美团搜索和我们实际的业务场景进行对比:先说说美团搜索场景。假如我们想在美团app上购买小吃,当我搜索“庙东排骨”时,我希望返回的搜索结果是和庙东排骨相关的商户。下图分别是美团app搜索场景和我们终端搜索场景:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图1 美团app搜索场景和我们终端搜索场景

对于用户来说,我希望搜索的结果是和庙东排骨相关的。要完成这件事,需要两个核心步骤:第一个是 理解用户搜索query ,第二个就是 把用户最感兴趣的搜索结果排在前面 。理解用户搜索query就是弄明白用户想要啥,因为用户表达需求主要通过文本数据,我们需要理解的对象是文本,所以属于自然语言处理范畴;把用户最感兴趣的搜索结果排在前面涉及召回和精排,属于推荐系统范畴。

了解了美团搜索的业务场景,下面看看我们业务搜索的场景。当用户使用手机终端的浏览器进行搜索,我们需要返回对应的结果。假如用户搜索oppo,我们希望返回和oppo相关的搜索结果。所以整体来看和美团搜索的场景非常类似,本质都是属于query-doc类的句子对关系任务。

02 计算query和doc相关性的方法

为了理解用户搜索query,需要计算用户搜索query和doc的相关性。根据计算方法的不同主要分成计算字面相关性和计算语义相关性两种。

1. 计算字面相关性

计算字面相关性主要是根据文本的匹配度,这里包括匹配的字数、匹配的比例等。这种方法可以从字面理解用户搜索query,但是存在以下两个缺点:

  • 词义局限:没有办法解决同义词和多义词的问题。比如“宾馆”和“旅店”这种同义词,虽然字面不同,但是都属于住宿相关;还有“苹果”这种多义词,既可以表示一种水果,还可以表示一个品牌;

  • 结构局限:同样两个词可以组成不同的组合词,但是表达的重点可能完全不同。比如“奶油蛋糕”和“蛋糕奶油”虽然词完全重合,但是前者重点在于蛋糕,后者则在于奶油,表达的意图完全不同。

2. 计算语义相关性

因为计算字面相关性存在语义局限和结构局限的问题,究其原因在于没有理解语义,所以业界提出了计算语义相关性,语义相关性模型主要包括传统的语义匹配模型和深度语义匹配模型。

2.1 传统的语义匹配模型

传统的语义匹配模型主要指隐式模型(典型代表是LDA主题模型)和翻译模型等,这里不是重点一笔带过。

2.2 深度语义匹配模型

与传统的语义匹配模型相对应的则是深度语义匹配模型。随着深度学习不断发展,业界兴起了基于深度学习的语义匹配模型,这也是本篇的重点。深度语义匹配模型主要分成基于表示的匹配方法和基于交互的匹配方法两种。

[1] 基于表示的匹配方法

基于表示的匹配方法主要使用深度学习模型来表示query和doc的embedding向量,通过计算向量相似度来表示语义相似度。最有代表性的就是微软提出的DSSM双塔模型。关于双塔模型之前出过一篇文章,有兴趣的小伙伴可以查看。对应于搜索推荐场景就是一方面获得代表query塔的embedding向量,另一方面获得代表doc塔的embedding向量。

基于表示的匹配方法优点在于 方便模型线上化 。搜索场景下我们可以提前获得doc的embedding并且存储到内存数据库中。线上只需要实时计算query的embedding向量,然后计算query和doc的embedding计算相似度即可。对于一些头部的query我们还可以提前将embedding向量存储在内存数据库中直接计算相似度。

基于表示的匹配方法缺点是 query和doc两者没有任何交互 ,无法应用一些业务场景下的匹配信号。比如一对query和doc可能在语义方面并没有什么关联,那么在基于表示的匹配方法下它们是不相似的。但是它们可能存在业务的联系,那么就可以通过业务数据构建他们的联系,这种关联则可以通过下面的基于交互的匹配方法获得。

[2] 基于交互的匹配方法

基于交互的匹配方法不会直接学习query和doc的embedding向量,而是 在构建神经网络时让query和doc进行交互,这样可以获得更好的文本表示 ,最后通过一个MLP网络获得语义匹配的得分。这种方法一般是监督学习的方式,在训练时能够进行充分的交互匹配,并且通过构建训练样本可以增加业务场景的关联,最终也能得到更好的文本表示。但是缺点是 不容易线上部署

3. 计算基于BERT的语义相关性

BERT是近几年NLP领域的里程碑之作,具备效果好和应用范围广的优点,广泛应用在学术界和工业界。BERT是典型的预训练和下游任务改造两阶段模型。预训练通过无监督的方式学习海量文本从而获取丰富的语言学知识;得到预训练网络后可以方便的应用到下游的实际任务中。基于BERT的语义匹配模型属于深度语义匹配模型,主要分成以下两种方式:

  • feature-based:这种方法对应于基于表示的匹配方法。将BERT作为编码器分别获得query和doc的embedding向量表示,然后将它们作为特征提供给下游推荐系统;

  • finetune-based:这种方式对应于基于交互的匹配方法,将query-doc转化为句子对关系任务进行训练。

美团搜索推荐项目主要使用BERT基于finetune-based的方法计算query和doc的相关性。

03 美团项目实践及思考

美团认为feature-based这种基于表示的匹配方法得到的query-doc是固定的,很难适配不同业务场景,同时海量的doc存储成本过高,最终选择了finetune-based这种基于交互的匹配方法。这里我认为feature-based得到的query和doc向量可以作为公共特征提供给下游不同的应用场景。这种DSSM双塔思想的方法从工程角度来看比较容易实现,对于一些业务比较紧急或者实力有限的公司使用这种feature-based方法是可行并且有效的。

美团搜索排序技术架构主要分成数据样本增强、BERT领域适配和核心排序模型优化三部分,具体架构图如下所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践 图2 美团搜索排序技术架构图

1. 数据样本增强

1.1 正负样本的划分

因为基于BERT的句子对关系任务属于有监督学习任务,所以需要一定的训练语料。美团搜索场景下的query和doc覆盖多个业务领域,如果每个领域都需要标注一批训练样本,那么需要消耗很多标注人力和时间。这里的解决办法是 根据用户搜索并且对应的浏览、点击和下单数据作为弱监督数据进行模型训练 。这里其实就是根据业务场景获取query和doc的关联,然后将这种关联在模型训练时进行充分的交互匹配,从而获得更好的文本表示。美团构造样本时采取业界常用的做法,对每个query抽取一个正样本和四个负样本。

1.2 样本去噪

上面讲到会将用户搜索并且对应的浏览、点击和下单数据作为弱监督数据进行模型训练。为什么说是弱监督数据呢?因为这种基于业务场景划分正负样本很容易产生噪声。比如很容易出现用户搜索query和doc本身是存在语义关联的,但是因为没有点击或者下单就作为负样本处理。针对容易产生噪声的情况,美团经过大量分析总结出以下几种方法进行样本去噪:

[1] 构造基准测试集

为了评测模型的离线效果,美团从构造样本中随机采样9K数据进行人工标注作为基准测试集。因为基准测试集是经过人工标注的,所以准确率较高,可以很好的评估模型的离线效果。

[2] 下单作为正样本

因为下单对于业务来说是用户行为中最具有价值的行为,可以强烈的表示用户的意图,所以直接将下单作为正样本。

[3] 将用户点击结果前的商家作为负样本

这里将用户点击前的商家作为负样本。举例说明,用户搜索完之后会返回N条商家信息,当用户浏览到第三条商户进行点击时则将第一和第二条作为负样本,这样可以有效剔除负样本的噪音。文章中称为基于Skip-Above的采样方式。

[4] 其他一些样本剔除规则

规则1:单字过滤。对于query来说,字数较少的query不仅无法表示用户的搜索意图,而且还会干扰模型,所以针对单字query直接进行过滤;

规则2:正样本中剔除query只出现在分店名中的样本。对于这种<大润发,小龙坎火锅(大润发店)>样本数据,虽然用户搜索query的意图是大润发,但是返回的结果主要是小龙坎火锅,所以需要剔除;

规则3:负样本中剔除带分店的商户。下单数据中存在商户和query语义相似,但因为不是距离用户最近商户所以没有被点击的负样本,比如<小龙坎,小龙坎(华阳店)>。这一类样本需要从负样本中剔除;

上述这些过滤规则是在实际业务中不断进行分析归纳总结的。 数据分析对于机器学习模型具有很重要的指导意义这一点深有感触。 在实际的NLP项目中当模型确定后,会花很多时间在样本工程上,这就类似传统机器学习项目中会花费很多时间在特征工程上。

1.3 品牌样本优化

关于品牌样本优化是极具美团特色的业务场景,因为在美团的商家中,存在很多一个品牌有多个商家的连锁店场景,这种情况下主要以品牌和地点组合来区分商户。对于用户搜索的品牌通过以下两种方式进行处理:

  • 如果用户只搜索了品牌名,那么表示用户真正有兴趣的是品牌,所以应该返回该品牌的商户。这里会将当前品牌下的不同分店统一映射为品牌进行召回,并且将其他品牌都作为负样本处理。这里实际业务场景应该会获取用户当前的定位,然后同时返回距离最近的该品牌分店。举例来说,如果用户搜索了“香格里拉酒店”,那么会将“香格里拉大酒店”、“北京香格里拉饭店”等都先映射为品牌名“香格里拉酒店”进行返回,同时其他品牌比如“希尔顿花园酒店”、“桔子酒店”等均作为负样本返回;

  • 如果用户同时搜索了品牌名和地点,那么表示用户有明确的目标,这里会将该品牌以及地点的商户返回。比如用户搜索了“香格里拉酒店北京”,那么正样本是“北京香格里拉饭店”,需要返回更精确的品牌分店了。

上述两种场景下对于用户搜索品牌的处理如下图所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图3 用户搜索品牌的处理策略

2. BERT领域适配

因为美团搜索推荐系统主要使用BERT模型,所以需要对BERT进行一系列的适配操作,主要分成预训练、微调以及模型轻量化三部分。

2.1 引入品类信息的预训练

Google开源的BERT预训练网络使用的是比较通用的文本数据,具有一定的普适性。但是通用性较强从另一方面来说就是缺乏一定的针对性。针对实际的业务场景,美团加入更多自己的数据去训练BERT模型,构建有自己业务特色的MT-BERT。虽然这种操作会让模型失去一定的通用性,但是也让模型更加 适配美团的业务场景 。美团基于自己的业务数据构建了餐饮娱乐领域的 知识图谱“美团大脑” 。将知识图谱中得到的地址、品类等属性数据用于预训练。这里举例说明引入品类信息的好处。假如现在有一条样本<考研班,红蝶教育>,单纯从语义来说两者毫无关联,但是根据知识图谱可以知道红蝶教育的三级品类信息是“教育-升学辅导-考研”,当模型训练时将红蝶教育的品类信息作为样本增强去帮助模型构建语义关联。这里的品类信息对应我们广告的类目体系。

这里主要将BERT模型适配为句子对关系任务。将句子对拼接成【cls考研班sep红蝶教育sep教育升学辅导考研sep】这样的格式作为模型文本输入。BERT原始的句子对任务只会有【cls语句1sep语句2sep】,这里将三级品类信息隔断又拼接在后面主要原因是 防止额外增加的信息对query和doc产生交叉干扰 。说到这里想起之前有一个项目实践是做汽车分类器,主要识别query是否属于汽车标签,任务类型属于文本分类。后来将任务改造成句子对关系任务,输入是【cls用户搜索sep汽车sep】,相当于去判断用户搜索query和语句”汽车”的相似关系,发现模型在测试集和线上真实数据集都有很大提升。这里仅把标签描述作为其中一个关键词,后续还可以挖掘汽车标签更多的关键词作为语句2,对于汽车的分类器识别效果会有更大的提升。

言归正传,下图是美团的MT-BERT模型对于文本输入的改造:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图4 MT-BERT模型改造文本输入

2.2 引入实体成分识别的多任务微调

美团在BERT微调阶段不仅考虑query-doc相似性任务,而且还引入了命名体识别任务。因为用户搜索query和商户doc中会出现很多实体成分,这些实体对于query-doc的相关性判断非常重要。比如用户搜索query“Helens海伦司小酒馆”和doc“Helens小酒馆(东鼎购物中心店)”,两者文本语义不完全匹配,但是实体成分相似。这种引入实体成分识别的多任务微调模型结构如下图所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图5 引入实体成分识别的多任务微调模型结构图

这种 语句相似关系任务和命名体识别任务相结合的思路可以很好的借鉴到我们当前的业务场景 。因为我们目前主要是对用户搜索query进行分类,用户搜索词一般较短,属于短文本识别,通过识别实体可以很好的辅助模型。多任务学习模型的损失函数分成相关性判断损失函数rele_loss和命名体识别损失函数ner_loss,两者相加即为最终需要优化的损失函数。

2.3 基于Pairwise的微调

要说基于Pairwise的微调,首先需要了解下Pointwise和Pairwise的关系。基于BERT的句子对关系任务是二分类任务,属于Pointwise。对应咱们的搜索推荐场景下训练样本是(query,doc,label),这里的label取值0或1。如果query-doc两者相关则为1,否则为0。 基于Pointwise的微调方法优势在于可以很好的学习到全局相关性 ,但是 缺点在于忽略了不同样本间的偏序关系 。对于同一个query,存在两个不同的docA和docB。Pointwise模型可以判断出query和docA、docB都相关,但是没有办法识别出docA和docB哪个更相关,也就是 将哪个doc排在更前面 。对于这个问题我以前以为通过对比query-docA和query-docB的得分高低来区分,但是实际情况是不一定得分高的就更适合排在前面。 为了让相关性特征对于排序结果更有区分度,参考了排序模型的Pairwise训练方式来优化BERT的微调任务

Pairwise的微调任务输入为(query,doc+,doc-),其中doc+代表和query相关的商户,doc-则代表和query不相关的商户。通过这种三元组作为输入样本,可以产出更具对比性的query-doc相关性特征。下面是基于Pairwise的微调模型结构图:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图6 基于Pairwise的微调模型结构图

3. 模型轻量化

原生BERT模型包含12层Transformer,网络结构复杂,参数量巨大,对于模型线上推理很不友好。这种情况下要想实现线上实时推理需要进行模型轻量化。通常情况下模型轻量化方法主要有以下三种:

  • 知识蒸馏:模型蒸馏主要是满足一定的精度前提下,将大模型学习到的知识迁移到轻量级的模型上,降低计算量的同时保证一定的预测效果。知识蒸馏可以理解成损失一定的精度从而提升模型的性能,综合权衡精度和性能的结果。关于BERT知识蒸馏的成果主要由HuggingFace提出的DistilBert和华为提出的TinyBert都有不错的效果。后续我们如果要做线上推理则可以使用知识蒸馏的方式;

  • 模型裁剪:模型裁剪则通过剪枝的方式减少参数的规模;

  • 低精度量化:低精度量化主要指在模型训练和推理中使用低精度代替原有精度,一般使用fp16、int8来替代fp32等。这种低精度量化更多的使用在移动终端上。

美团对比了原生模型和知识蒸馏、模型裁剪两种方法在准确率和AUC指标上的变化。原生BERT模型使用12层Transformer,轻量化之后变成了两层Transformer,通过对比发现知识蒸馏效果较好。 为了解决线上实时推理问题,美团最终使用知识蒸馏对BERT进行压缩 。实验对比数据如下表所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

表1 实验对比知识蒸馏和剪枝的效果

4. 联合训练

基于BERT的搜索推荐主要分成两块,第一块是训练BERT相关性模型,也就是计算query和doc的相似性;第二块是训练排序模型,也就是将用户真正感兴趣的商户排在前面。 为了在排序模型训练中引入更多相关性信息,美团将原本两阶段的BERT相关性微调任务和排序任务进行了端到端的联合训练。 不仅如此,美团还将联合训练得到的embedding作为“共享特征”,提供给下游不同场景业务使用。这种基于Partition-model的BERT相关性任务和排序任务的联合训练模型可以说是 有美团特色的预训练模型 ,利用所有数据进行训练,将模型训练得到的embedding作为特征再提供给下游业务使用,做到了“ 一次训练,多次使用 ”的效果。下面是联合训练的模型结构图:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图7 联合训练模型结构图

  • 输入层:最底层是输入层,主要由文本特征向量、用户行为序列特征向量和其他特征向量三部分组成。(1)文本特征向量:文本特征向量主要由BERT模型进行抽取,包括商户、品牌等信息。将文本数据提供给MT-BERT,得到CLS向量作为文本的语义特征向量;(2)用户行为序列特征向量:用户行为序列特征向量主要由Transformer进行抽取;(3)其他特征向量:其他特征向量主要包括统计类特征、文本特征、传统的文本相关性特征等。统计类特征是query、doc等维度的特征以及交叉特征,主要作用是丰富query和doc的表示,辅助模型训练;这里的文本特征更多的是将文本数据分词后得到的word embedding;传统的文本相关性特征则代表基于Term匹配得到的文本向量,包括匹配字数、比例等等,更多的是字面程度的信息辅助模型训练;

  • 共享层:将所有数据得到的特征向量作为“共享特征”提供给下游不同的业务方使用;

  • 场景层:这里主要是根据不同的业务场景构建自己特有的网络,具有定制化作用;

  • 损失函数:最后采用优化NDCG的LambdaLoss的损失函数,将用户感兴趣的搜索结果排在前面,提升用户的体验。

这里需要注意的是将所有数据经过加工得到的共享特征可以有效提升数据的利用率,为其他业务团队提供可靠的特征。

5. 排序服务架构优化

为了适应模型线上推理,美团对排序服务架构进行优化,搜索线上排序服务框架如下图所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

图8 搜索线上排序服务框架图

整个线上排序服务框架分成三大块:

  • 模型在线预估框架(Augur):这是美团开发的在线预估框架,主要支持语言化定义特征,配置化加载和卸载模型和特征,支持主流线性模型和TF模型的在线预估。为了方便BERT特征用于排序模型,美团开发了Model Stacking功能,很好的支持了BERT as Feature;

  • 搜索模型实验平台(Poker):这是美团开发的模型实验平台,主要支持大规模数据提取和模型离线特征抽取、模型训练。训练好的模型可以实现一键上线,有效的提升了模型的实验效率;

  • TF-Serving在线模型服务:这里主要使用TF-Serving的方式部署BERT线上推理模型、排序模型等,支持Faster Transformer加速BERT推理,提升线上预测速度。

通过模型在线预估框架、搜索模型实验平台和TF-Serving在线模型服务很好的实现了排序服务架构优化。整个架构非常具有参考价值,也可以看出美团深厚的技术底蕴,这里不得不服。

6. 各种优化策略对比

整体来看,美团主要通过样本去噪、品牌信息、品类知识、Pairwise等优化策略对搜索排序模型进行优化。对照组是当前未做任何优化的排序模型,各优化策略带来的效果提升如下表所示:

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践

表2 各优化策略带来的效果提升

从表中可以看出上述优化策略都一定程度上提升了搜索排序模型的效果。对于我们实际业务场景也极具借鉴价值:其中 基于知识图谱技术的品牌信息和品类知识给模型带来的提升效果最明显 ,这也说明了搜索场景下尤其短文本场景中加入辅助知识可以大幅度提升模型的线上效果; 样本去噪带来的模型提升也很大 ,进一步说明了底层数据的清洗、加工和分析对于模型线上效果的重要作用;基于Pairwise的微调方法对于模型AUC提升很大,这种策略主要对排序模型效果显著,后续可以进行尝试。

总结

本篇主要分析BERT在美团搜索排序中的项目实践。首先介绍了业务背景,主要对比了美团搜索业务场景和我们的应用场景;然后讲了计算query和doc相关性的方法,主要包括计算字面相关性和计算语义相关性,同时重点讲了计算基于BERT的语义相关性内容;最后也是本篇的重点,分析了美团搜索排序项目实践以及对我们业务的思考,其中包括数据样本增强、BERT领域适配、模型轻量化、联合训练和排序服务架构优化等一系列眼花缭乱但是又极具工程价值的优化操作,对于我们有极大的工程借鉴价值。不得不说美团深厚的技术底蕴,也推荐小伙伴们关注美团技术团队的文章,干货不断。

参考资料

[1] BERT在美团搜索核心排序的探索和实践

[2] 美团餐饮娱乐知识图谱——美团大脑揭秘

[3] 大众点评搜索基于知识图谱的深度学习排序实践.

最新最全的文章请关注我的微信公众号:数据拾光者。

广告行业中那些趣事系列15:超实用的基于BERT美团搜索实践


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法心得:高效算法的奥秘(原书第2版)

算法心得:高效算法的奥秘(原书第2版)

(美)Henry S. Warren, Jr. / 爱飞翔 / 机械工业出版社 / 2014-3 / 89.00

【编辑推荐】 由在IBM工作50余年的资深计算机专家撰写,Amazon全五星评价,算法领域最有影响力的著作之一 Google公司首席架构师、Jolt大奖得主Hoshua Bloch和Emacs合作创始人、C语言畅销书作者Guy Steele倾情推荐 算法的艺术和数学的智慧在本书中得到了完美体现,书中总结了大量高效、优雅和奇妙的算法,并从数学角度剖析了其背后的原理 【读者评价......一起来看看 《算法心得:高效算法的奥秘(原书第2版)》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具