WeNet2.0:提高端到端ASR的生产力

news2024/11/18 9:33:41

摘要

最近,我们提供了 WeNet [1],这是一个面向生产(=工业生产环境需求)的端到端语音识别工具包,在单个模型中,它引入了统一的两次two-pass (U2) 框架和内置运行时(built-in runtime)来处理流式和非流式解码模式。

为了进一步提高 ASR 性能并满足各种生产需求,在本文中,我们介绍了 WeNet 2.0 的四个重要更新。

  • 我们提出了 U2++,这是一个具有双向注意力解码器的统一双通道框架(two-pass framework with bidirectional attention decoders),其中包括从右到左注意力解码器(注意,是right-to-left方向!)的未来上下文信息,以提高共享编码器的表示能力(representative ability)和重新评分阶段(rescoring stage)的性能。

  • 我们在 WeNet 2.0 中引入了基于 n-gram 的语言模型和基于 WFST 的解码器,促进了富文本数据(rich text data)在生产场景中的使用。 【这个好!可以说,上一代的代表kaldi的重要的功能,目前在WeNet2.0中进行很好的idea和方法论的继承和实现】

  • 我们设计了一个统一的上下文偏置框架(unified contextual biasing framework),该框架利用用户特定的上下文(例如联系人列表-contact lists)为生产提供快速适应能力,并在“有 LM” 和“无 LM”两大场景中提高 ASR 准确性。

  • 我们设计了一个统一的 IO 来支持大规模数据进行有效的模型训练。

综上所述,全新的 WeNet 2.0 在各种语料库上比原来的 WeNet 实现了高达 10% 的相对识别性能提升,并提供了几个面向生产的重要特性。

索引词:U2++,语言模型,上下文偏置(contextual biasing),UIO

论文地址:https://arxiv.org/pdf/2203.15455.pdf

github地址:https://github.com/wenet-e2e/wenet

1 简介

端到端 (end-to-end, E2E) 方法,例如连接主义时间分类 (connectionist temporal classification - CTC) [2, 3]、循环神经网络转换器 (RNN-T) [4, 5, 6, 7] 和基于注意力的编码器-解码器 ( attention-based encoder-decoder: AED) [8, 9, 10, 11, 12],在过去几年中引起了对自动语音识别 (ASR) 的极大兴趣。

最近的工作 [13, 14, 15] 表明 E2E 系统不仅极大地简化了语音识别管道,而且在准确性上也超过了传统的混合 ASR 系统(hybrid ASR systems)。

考虑到 E2E 模型的优势 [16],将新兴的 E2E ASR 框架部署到具有稳定和高效特性的实际生产中变得很有必要。然而,几乎所有著名的 E2E 语音识别工具包,例如 ESPnet [17] 和 SpeechBrain [18],都是面向研究而非面向生产的。【鉴于ESPnet是几位日本人研究者开发的,所以,对于日文的支持,有一定的优势。一些日本的企业,也仍然在使用ESPnet来训练他们的ASR模型。】

在 [1] 中,我们提出了一个生产优先和生产就绪(production first and production ready = PFPR,这个词好!)的 E2E 语音识别工具包 WeNet1,它专注于解决实际生产中基于 Transformer [19] 或 Conformer [20] 的 E2E 模型的棘手问题。

具体来说,WeNet 采用联合 CTC/AED (例如,主要是指综合ctc loss和attention loss)结构作为基本模型结构。然后,提出了一个统一的两通(two-pass,U2)框架来解决流式传输问题,其中在训练过程中应用动态块掩码策略(dynamic chunk masking)将流式和非流式模式统一在一个统一的神经模型中,并提供“构建运行时”(built-in runtime),开发人员可以在其中运行 x86 和 android E2E 系统以进行开箱即用的语音识别。

WeNet 极大地减少了在实际应用中部署 E2E 模型的工作量,因此被研究人员和开发人员广泛采用,用于在实际生产中实现语音识别。

在本文中,我们介绍了 WeNet 2.0,它介绍了 WeNet 中最新的发展和更新的解决方案,用于面向生产的语音识别。 WeNet 2.0 的主要更新如下。

  • U2++:我们将原来的U2框架升级为U2++(嗯!估计下次再升级,就是U2#了,++++),同时利用标注序列的从左到右从右到左的双向上下文信息,在训练阶段学习更丰富的上下文信息,结合前向和反向预测,以在解码阶段获得更准确的结果。实验表明,与原始 U2 框架相比,U2++ 实现了高达 10% 的相对改进(细节代码学习,后续安排上!TODO)
  • 生产(产品-production)语言模型解决方案:我们支持一个可选的 n-gram LM,在流式 CTC 解码阶段,它将与基于加权有限状态自动机 (WFST) [21] 的解码图中的 E2E 建模单元组成。

n-gram LM 可以在丰富的生产积累文本数据上快速训练,这是面向生产的重要特征。实验表明,n-gram 语言模型可以提供高达 8% 的相对性能提升(这也凸显了基于更大规模文本语料,训练出来的语言模型,的有效性!)

  • 上下文偏置(contextual biasing):我们设计了一个统一的上下文偏置框架,它提供了在流解码阶段利用或不使用 LM 的用户特定上下文信息的机会。利用用户特定的上下文信息(例如,联系人列表、特定对话状态、呈现给用户的选项、对话主题、位置等)在提高 ASR 准确性和在语音生成中提供快速适应能力方面发挥着重要作用。【这个对于很多场景有用:例如长时间的电话会议的会议内容转录,长时间的视频的语音理解,等等!】实验表明,我们的上下文偏差解决方案可以为有 LM 和没有 LM 的情况带来显着的改进。
  • 统一IO(UIO):我们设计了一个统一的IO系统来支持大规模数据集进行有效的模型训练。 UIO 系统为不同的存储(即本地磁盘或云)和不同规模的数据集(即小型或大型数据集)提供统一的接口。

对于小型数据集,UIO 保持样本级随机访问能力。而对于大型数据集,UIO 将数据样本聚合到分片shard(有关详细信息,请参阅图 4)并提供分片级随机访问能力

多亏有了 UIO,WeNet 2.0 可以弹性地支持几小时到数百万小时数据的训练

总而言之,我们全新的 WeNet 2.0 提供了几个重要的面向生产的功能,与原始 WeNet 相比,它实现了显著的 ASR 改进,并使其自身成为更高效的 E2E 语音识别工具包。

2 WeNet 2.0

在本节中,我们将分别详细描述面向生产的关键更新:U2++ 框架、生产语言模型解决方案、上下文偏置和统一 IO。

2.1 U2++

U2++ 是一个统一的两通(two-pass)联合 CTC/AED 框架,带有双向注意力解码器,为统一流式和非流式模式提供了理想的解决方案。

U2++框架;左边一路是ctc loss;右边是attention decoder/loss(而且右边又包括了,从左到右,从右到左的两个方向)

如图1所示,U2++由四部分组成。

1) 对声学特征信息进行建模的共享编码器(shared encoder)。

共享编码器由多个 Transformer [19] 或 Conformer [20] 层组成,它们只考虑有限的右侧上下文(limited right contexts)以保持平衡的延迟(balanced latency)。

2) 一个 CTC 解码器,它对声学特征(acoustic features)和token单元(token units)之间的帧级对齐信息(frame-level alignment information)进行建模。

CTC 解码器由一个线性层组成,它将共享编码器输出转换为 CTC 激活。

3)一个从左到右的注意力解码器(L2R),它对从左到右的有序标记序列进行建模,以表示过去的上下文信息

4)一个从右到左的注意力解码器(R2L),它对从右到左的反向标记序列进行建模,以表示未来的上下文信息

L2R 和 R2L 注意力解码器由多个 Transformer 解码器层组成。

在解码阶段,CTC 解码器在第一遍以流模式运行,L2R 和 R2L 注意力解码器在非流模式下重新评分,以提高第二遍的性能。

与 U2 [1] 相比,我们增加了一个额外的从右到左注意力解码器来增强我们模型的上下文建模能力,使得上下文信息不仅来自过去(从左到右解码器),而且来自未来(从右到左的解码器)

这提高了共享编码器的代表能力、整个系统的泛化能力以及重新评分阶段的性能。

组合 CTC 和 AED 损失Losses,用于训练 U2++:

与U2类似,采用动态块掩码策略(dynamic chunk masking strategy)来统一流式(streaming)和非流式(non-streaming)模式。

训练阶段,我们首先从均匀分布 :

C ∼ U(1, max batch length T)

中采样一个随机块大小 C。

然后,输入被分成几个具有所选块大小的块。

最后,当前块在训练中分别对自身和 L2R/R2L 注意力解码器中的前/后块进行双向块级注意(注意力的计算)

解码阶段,从第一遍 CTC 解码器获得的 n-best 结果由 L2R 和 R2L 注意力解码器重新评分,其相应的声学信息由共享编码器生成。

根据经验,更大的块大小会导致更好的结果和更高的延迟。

由于采用了动态策略,U2++ 学会了使用任意块大小进行预测,从而可以通过“在解码中调整块大小”来简化准确性和延迟的平衡。

2.2.语言模型

为了促进富文本数据在生产场景中的使用,我们在 WeNet 2.0 中提供了统一的 LM 集成框架,如图 2 所示。

通过 n-best 结果。

其一,当没有提供 LM 时,应用 CTC 前缀波束搜索(CTC prefix beam search)来获得 n 个最佳候选。

其二,当提供了 LM 时,WeNet 2.0 将 n-gram LM (G)词典 (L) 和端到端建模 CTC 拓扑 (topology-T) 编译成基于 WFST 的解码图 (TLG)

TLG = T ◦ min(det(L ◦ G)), (3)

然后应用 CTC WFST 波束搜索来获得 n 个最佳候选。

最后,通过 Attenion Rescoring 模块对 n 个最佳候选者进行重新评分,以找到最佳候选者。

我们重用 Kaldi[22] 中的算法和代码进行解码,在 WeNet 2.0 框架中表示为 CTC WFST 波束搜索

为了加快解码速度,采用了空白帧跳过(blank frame skipping)[23]技术。

2.3.上下文偏置

利用用户特定(user-specific)的上下文信息(例如,联系人列表、驾驶员导航)在语音生成中起着至关重要的作用,它始终显著提高准确性提供快速适应能力

在 [24, 25, 26] 中研究了传统和 E2E 系统的上下文偏置(contextual biasing)技术。

在 WeNet 2.0 中,为了在流解码阶段利用 LM 和无 LM 情况下的用户特定上下文信息,受 [25] 的启发,我们在已知一组偏置短语时,动态构建“上下文相关的 WFST 解码图”

we construct a contextual WFST graph on the fly when a set of biasing phrases are known in advance.

首先,根据 LM-free 情况下的 E2E 建模单元(E2E modeling units)或 with-LM 情况下的词汇词(vocabulary words),将偏置短语拆分为偏置单元(biasing units)。

然后,“上下文相关 WFST 图”,按如下方式动态构建:

(1)每个具有提升分数(boosted score)的偏置单元(biasing unit)按顺序放置在相应的弧上,以生成可接受的链(acceptable chain)

(2) 对于可接受链的每个中间状态(intermediate state),添加一个具有负累积提升分数(negative accumulated boosted score)特殊失败弧(special failure arc)

当仅匹配部分偏置单元而不是整个短语时,失败弧(failure arc)用于移动提升的分数(move the boosted scores)。

在上面的图 3 中,分别显示了:

LM-free 情况下的 char(E2E 建模单元)级【单个文字】上下文图,和,

with-LM 情况下的单词级【不忘+初心】上下文图。

最后,在流式(streaming)解码阶段,当波束搜索结果,通过“上下文相关的 WFST 图”与偏置单元匹配时,立即添加一个 boosted score,如

其中 P_C (y) 是偏置分数,λ 是一个可调超参数,用于控制上下文 LM 对整体模型分数的影响程度。

特别是当一些有偏见的短语共享相同的前缀时,我们会进行贪婪匹配以简化实现。

2.4. UIO

通常,生产规模的语音数据集包含数万小时的标记语音,其中始终包含大量小文件

海量的小文件会导致以下问题:

• 内存不足(OOM):我们必须保留所有小文件的索引信息,这对于大型数据集来说非常消耗内存。

• 训练速度慢:随机访问海量小文件时,读取数据的时间非常长,成为训练的瓶颈。

针对上述大规模生产数据集的问题,同时保持小数据集的高效率,我们设计了一个统一的IO系统,为不同的存储(即本地磁盘或云)和不同的规模提供统一的接口数据集(即小型或大型数据集)

整个框架如图 4 所示。

对于大型数据集,受 TFReord (Tensorflow) [27] 和 AIStore [28] 的启发,我们将每个批处理的较小样本(例如 1000 个样本)及其相关元数据信息打包到相应的更大分片中,这是由 GNU tar 完成的,它是一种开源、开放格式、无处不在且得到广泛支持的存档工具。

Tar 文件显着节省内存并有效克服 OOM 问题。在训练阶段,在内存中进行on-the-fly(在线,动态)解压,顺序读取同一个压缩分片中的数据,解决了随机数据访问的耗时问题,加快了训练过程

同时可以随机读取不同的分片,保证数据的全局随机性。对于小数据集,我们也可以直接加载训练样本。特别是在大数据集使用分片时,我们支持从本地磁盘和分布式存储(例如 S3、OSS、HDFS 等)加载分片。与TFRecord类似,设计了即时处理数据的链式操作,使统一IO可扩展且易于调试。

3 实验

在本节中,我们将描述我们的实验设置、测试集并分析实验结果。 WeNet recipes 中提供了大多数实验设置。

实验在以下全部或部分语料库上进行:

  1. AISHELL-1 [29]、
  2. AISHELL-2 [30]、
  3. LibriSpeech [31]、
  4. GigaSpeech [32] 和最近发布的
  5. WenetSpeech [33]。

这五个语料库包括不同的语言(英语和普通话)、录制环境(干净和嘈杂)和大小(100 - 10000 小时)。

3.1 U2++

为了评估我们的 U2++ 模型的有效性,我们对上面列出的所有 5 个 ASR 语料库进行了实验。对于大多数实验,具有 25ms 窗口和 10ms 偏移的 80 维 log Mel 滤波器组 (FBANK) 用作声学特征。

SpecAugment [34] 即时应用于数据增强。

在编码器的前面使用了两个内核大小为 3*3 和步幅为 2 的卷积子采样层。

我们的编码器中,使用 12 个conformer layers。

为了保持 U2/U2++ 的可比参数,我们为 U2 使用 6 个transformer 解码器层,为 U2++ 使用 3 个从左到右和 3 个从右到左的解码器层。

此外,我们通过模型平均(model averaging)获得最终模型。

在 AISHELL-1 和 AISHELL-2 中,注意力层使用注意力维度 256、前馈 2048 和 4-head attention。

在 LibriSpeech、GigaSpeech 和 WenetSpeech 中,注意力层使用注意力维度 512、前馈 2048 和 8-head attention。

五个语料库的卷积模块的内核大小分别为 8/8/31/31/15。累积梯度用于稳定训练(accumulated gradient,例如如果batch=16,累计梯度=2,那么其实是32个样本,更新一次梯度的adam等优化搜索)。

在表 1 中,我们报告了每个语料库的:

字符错误率 (CER)、单词错误率 (WER) 或混合错误率 (MER)

它表明 U2++ 在大多数语料库上都优于 U2,并且相对于 U2 实现了高达 10% 的相对改进。

从结果来看,我们认为 U2++ 在各种类型和大小的 ASR 语料库中始终表现出优异的性能

3.2. N-gram 语言模型

语言模型解决方案在 AISHELL-1、AISHELL-2 和 LibriSpeech 上对第 3.1 节中列出的模型进行评估。对于 AISHELL-1 和 AISHELL-2,使用在其自己的训练语料库上训练的 tri-gram。

对于 LibriSpeech,使用了官方预训练的4-gram大语言模型(fglarge)。

为了加快解码速度,当一帧“空白”符号的概率大于 0.98 时,将跳过该帧

表 2 展示了三个语料库在有 LM 和无 LM 场景中的比较结果。 with-LM 解决方案在 AISHELL-1 上显示 5% 的增益,在 AISHELL-2 上的可比结果,在 LibriSpeech 上测试清洁的可比结果,以及在 LibriSpeech 上的其他测试中的卓越改进 (8.42%)。

总之,我们的生产 LM 解决方案在三个语料库上显示出一致的增益,这说明 n-gram 语言模型在集成到 E2E 语音识别系统时效果很好

得益于该方案,生产系统(production system)可以享受到丰富的生产积累文本数据。

3.3.上下文偏置

我们评估接触场景中的上下文偏置,我们设计了两个从 AISHELL-2 测试集中选择的测试集

• test_p:带有相关上下文的正测试集(positive test set)。我们选择了 107 个带有人名的话语,所有的人名在解码时都作为上下文偏置短语附加。

• test_n:在正测试集中没有任何上下文偏置短语(即名称)的负测试集(negative test set)

我们随机选择 107 个符合条件的话语作为负测试集()。我们在有和没有 LM 的 AISHELL-1 U2++ 模型上进行了测试。我们表明,可以通过切换提升分数来控制上下文偏差的强度。在我们的实验中,提升分数从 0 到 10 不等,其中 0 表示未应用上下文偏差。

如表 3 所示,我们的解决方案降低了正测试集的错误率,并且更大的提升分数通常会带来更好的改进。

此外,当设置适当的提升分数时,我们可以提高正测试集的性能,同时避免负测试集的性能下降

3.4. UIO

我们评估了 UIO 在 AISHELL-1 [29] 和 WenetSpeech [33] 上的性能,包括准确性、可扩展性和训练速度。

具体来说,我们在一台机器上为 AISHELL-1 使用 8 个 GPU在三台机器上为 WenetSpeech 使用 24 个 GPU

如表 4 所示,UIO 在 AISHELL-1 上的 raw 和 shard 模式下显示出接近的准确性,而 shard 模式在训练速度方面得到了大约 9.27% 的加速。

对于 WenetSpeech,由于只使用 raw 模式进行训练太慢,所以没有显示训练速度。我们采用 ESPnet 的结果(标有†)作为我们的基线,它与我们的模型具有相同的配置。

通过分片模式在 WenetSpeech 上训练的模型的结果与 ESPnet 相当,这进一步说明了 UIO 的有效性

4 结论和未来工作

在本文中,我们提出了更具生产力的 E2E 语音识别工具包 WeNet 2.0,它引入了几个重要的面向生产的特性并实现了显著的 ASR 性能改进。

我们正在开发 WeNet 3.0,主要专注于无监督自学习、设备端模型探索和优化以及其他生产工作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1384985.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPF 布局

了解 WPF中所有布局如下,我们一一尝试实现,本文档主要以图形化的形式展示每个布局的功能。 布局: Border、 BulletDecorator、 Canvas、 DockPanel、 Expander、 Grid、 GridView、 GridSplitter、 GroupBox、 Panel、 ResizeGrip、 Separat…

怎样制作一本旅游电子相册呢?

​随着数码技术的发展,旅游电子相册已成为越来越多旅游爱好者的必备工具。它不仅能让您随时随地欣赏自己的旅行回忆,还能分享给亲朋好友,甚至上传到社交媒体上,让更多人了解您的旅行故事。那么,如何制作一本精美的旅游…

HarmonyOS4.0系列——05、状态管理之@Prop、@Link、@Provide、@Consume,以及@Watch装饰器

状态管理 看下面这张图 Components部分的装饰器为组件级别的状态管理,Application部分为应用的状态管理。开发者可以通过StorageLink/LocalStorageLink 实现应用和组件状态的双向同步,通过StorageProp/LocalStorageProp 实现应用和组件状态的单向同步。…

智能路由器中的 dns.he.net可使用自定义域名的免费 DDNS 服务配置方法

今天介绍的这个是可以使用自定义域名同时支持使用二级域名的免费DDNS服务 dns.he.net的动态DDNS服务的配置方法, 这个服务相对还是比较稳定的, 其配置也和其他的DDNS服务有些不太一样, 首先他的主机名: 这里需要设置为登录后分配的区域域名: ipv6.he.net 然后就是 DDNS 用户…

cad二次开发autolisp(一)

文章目录 一、概述1.1 简介1.2 打开编辑器1.3 调试页面 二、数据类型三、函数3.1 用户函数 四、语句4.1 常规语句4.2 流程控制语句 五、图元操作5.1 定义5.2 图元选择5.3 图元属性列表 一、概述 1.1 简介 简介:cad 二次开发语言,后缀名*.lsp适用于编写…

tda7294引脚功能和电压_三款tda7294应用电路

tda7294引脚功能 1脚为待机端; 2脚为反相输入端; 3脚为正相输入端; 4脚接地; 5、11、12脚为空脚; 6脚为自举端; 7脚为Vs(信号处理部分); 8脚为-Vs(信号…

分布式计算平台 Hadoop 简介

Hadoop简介 Hadoop是一种分析和处理大数据的软件平台,是一个用Java语言实现的Apache的开源软件框架,在大量计算机组成的集群中实现了对海量数据的分布式计算。其主要采用MapReduce分布式计算框架,包括根据GFS原理开发的分布式文件系统HDFS、…

解锁 JavaScript 数组的强大功能:常用方法和属性详解(上)

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…

使用Qt连接scrcpy-server控制手机

Qt连接scrcpy-server 测试环境如何启动scrcpy-server1. 连接设备2. 推送scrcpy-server到手机上3. 建立Adb隧道连接4. 启动服务5. 关闭服务 使用QTcpServer与scrcpy-server建立连接建立连接并视频推流完整流程1. 开启视频推流过程2. 关闭视频推流过程 视频流的解码1. 数据包协议…

C++进阶--AVL树

AVL树 一、AVL树的概念二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转4.1 左单旋4.2 右单旋4.3 左右双旋4.4 右左双旋 五、AVL树的验证六、AVL树的删除七、AVL树的性能七、完整代码7.1 AVLTree.h 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有…

命令行登录Mysql的详细讲解

目录 前言1. 本地登录2. 远程登录3. 拓展 前言 对于命令行登录Mysql一般都是用mysql -u root -p 但对于如何远程登陆,一直其他的参数还是有些盲区,对此总结科普 对于登录过程中出现的问题,可看我之前的文章: 服务器 出现ERROR …

CTF伪随机数爆破

要了解伪随机数的爆破首先你的先知道什么是PHP种子, 借用在rand()函数中,我们可以通过设置随机数种子来影响随机数的生成。例如,在rand()函数中加入了随机数种子编码后,每次运行程序将会生成同样的随机整数序列。这个就是伪随机数…

Python实现对角但非同一性协方差结构回归模型(WLS算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 WLS回归分析是一种常用的回归分析方法,通过对数据进行加权处理,可以更准确地评…

CNN:Convolutional Neural Network(上)

目录 1 为什么使用 CNN 处理图像 2 CNN 的整体结构 2.1 Convolution 2.2 Colorful image 3 Convolution v.s. Fully Connected 4 Max Pooling 5 Flatten 6 CNN in Keras 原视频:李宏毅 2020:Convolutional Neural Network 1 为什么使用…

计算机毕业设计 基于Java的国产动漫网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

HCIP 重发布

拓扑图&IP划分如下: 第一步,配置接口IP&环回地址 以R1为例,R2~R4同理 interface GigabitEthernet 0/0/0 ip address 12.1.1.1 24 interface GigabitEthernet 0/0/1 ip address 13.1.1.1 24 interface LoopBack 0 ip address 1.1.1.…

redis7部署集群

前言: redis部署集群常见的一般有三种模式:主从模式,Sentinel(哨兵模式),Redis Cluster(高可用Cluster集群),根据不同的需求可自定义选择部署方式。 Redis 主从模式&…

开发实践5_后台管理^/ 分_页器

以下学习 朔宁夫 开发课 。(Python) 一 基本使用 创建超级用户 terminal // python manage.py createsuperuser 访问地址 //Log in | Django site adminhttp://127.0.0.1:8000/admin/login/?next/admin/ superuserr login django自带admin功能。其…

深入理解 go reflect - 要不要传指针

在我们看一些使用反射的代码的时候,会发现,reflect.ValueOf 或 reflect.TypeOf 的参数有些地方使用的是指针参数,有些地方又不是指针参数, 但是好像这两者在使用上没什么区别,比如下面这样: var a 1 v1 :…

你好2024,OpenStreetMap 20 周岁

2004年,OpenStreetMap在英国诞生。2024年,OpenStreetMap 满 20 周岁,其愿景是创建一个免费的、可编辑的世界地图。当时,地图数据的获取往往受到限制或价格昂贵1。 经过20年的发展,该数据集合成为了最为全面的街道级别开…