学习

使用 RedisGears 构建自然语言处理 (NLP) 流水线

Alex Mikhalev
作者
Alex Mikhalev, Nationwide Building Society 的 AI/ML 架构师
Ajeet Raina
作者
Ajeet Raina, Redis 前开发者增长经理

目标#

在本教程中,您将学习如何使用 RedisGears 构建自然语言处理 (NLP) 流水线。本次演示将利用 Kaggle CORD19 数据集。该实现旨在避免内存耗尽,利用 Redis Cluster 和 RedisGears。RedisGears 允许在存储上直接处理数据,无需将数据移进移出 Redis Cluster,从而将 Redis Cluster 用作数据结构层。Redis Cluster 支持高达 1000 个节点的横向扩展,与 RedisGears 结合使用时,它提供了一个分布式系统,数据科学/ML 工程师可以专注于处理步骤,而无需担心为分布式计算编写大量样板代码。

构建此项目的目的是让其他人更容易贡献力量,并构建更好的信息和知识管理产品。

为什么数据科学家使用 RedisGears?#

RedisGears 潜力巨大,特别是对于文本处理——您可以在“数据上”处理数据,无需将其移进移出内存。重要要点总结:

  • 内存存储(如果是 Redis cluster,则可横向扩展)
  • 处理数据(在数据上),无需移进移出
  • Gears - 类似于 Hadoop 上的 Spark,在存储(内存)上智能处理数据,无需移进移出数据
  • 启用 RedisGears 和 Python 的 Redis 集群模式仅占用 20MB RAM。想想您可以向笔记本电脑或服务器中载入多少更多数据。

什么是知识图谱?#

如今,我们生活在一个新系统世界中,这些系统不仅处理文件、文件夹或网页,还处理具有自身属性和相互关系的实体,并将它们组织成类和类别的层级结构。这些系统无处不在,从军工联合体到我们的日常生活。Palantir、Primer 和其他数据公司在军事和安全部队中实现了大规模的情报和反情报项目;Quid 和 RecordedFuture 实现了竞争分析;Bottlenose 和类似企业实现了在线声誉分析。Microsoft Graph 为企业带来了新型生产力应用,Google Knowledge Graph 和 Microsoft 的 Satori 实现了日常搜索查询,它们与 Amazon Information Graph 一起,通过使其能够回答关于世界事实的问题,为相应的 AI 助手提供支持。

所有这些(以及许多其他更专业的)系统都用于不同的领域,但它们都以知识图谱作为基础。

知识图谱是连接和理解来自不同数据源信息的最佳方式之一,遵循了某个供应商的座右铭——“重在事物,而非字符串”

知识图谱由同义词库、分类法和本体构成。在此流水线中,我假设知识存储在医学元同义词库 UMLS 中,并且文本中的概念在同一句话中时相互关联,因此概念成为节点,它们的关系成为边。

概念具有 CUI(概念唯一标识符),这些标识符将作为节点的 主键,并链接到 UMLS 同义词库。例如,如果您在演示网站 http://thepattern.digital/ 上搜索“温度和湿度如何影响 2019-nCoV 的传播?”,并将滑块移到 1996 年,则会有一条边连接传播(C5190195)和出生(C5195639),并匹配到句子中的“传播给所生婴儿的速率”部分,该部分来自题为“婴儿的无热肺炎”的报告。

用于 NLP 预处理的 RedisGears#

整体架构概览(组件图)#

摄取步骤(Intake step)非常简单,将所有 JSON 记录放入 RedisCluster,然后 NLP 流水线开始处理所有记录,代码位于 此处

NLP 流水线步骤如何融入 RedisGears?#

  1. 1.对于每条记录 — 检测语言(丢弃非英语记录),这是一个 filter(过滤)操作
  2. 2.将段落映射成句子 — 这是一个 flatmap 操作
  3. 3.句子拼写检查 — 这是一个 map 操作
  4. 4.将句子保存到 hash 中 — 这是一个 processor 操作

步骤 1. 前提条件#

确保您的系统安装了 virtualenv

步骤 2. 克隆代码库#

 git clone --recurse-submodules https://github.com/applied-knowledge-systems/the-pattern.git
 cd the-pattern

步骤 3. 启动应用#

 docker-compose -f docker-compose.dev.yml up --build -d

步骤 4. 应用集群配置设置#

您可以部署 PyTorch 和 spacy 在 RedisGears 上运行。

 bash post_start_dev.sh
提示

对于面向数据科学的部署,RedisCluster 应处于 HA 模式,每个 master 至少有一个 slave。需要更改 rgcluster 的一些默认参数以适应 PyTorch 和 spacy 库的大小(每个压缩后超过 1GB),设置的 gist 在此。

步骤 5. 创建或激活 Python 虚拟环境#

 cd ./the-pattern-platform/

步骤 6. 创建新环境#

您可以通过以下方式创建

 conda create -n pattern_env python=3.8

或者,您可以使用以下 CLI 命令激活

 source ~/venv_cord19/bin/activate #or create new venv
 pip install -r requirements.txt

步骤 7. 运行流水线#

 bash cluster_pipeline.sh

步骤 8. 验证 NLP 流水线的功能#

稍等片刻,然后检查

验证 Redis Graph 已填充:#

 redis-cli -p 9001 -h 127.0.0.1 GRAPH.QUERY cord19medical "MATCH (n:entity) RETURN count(n) as entity_count"
 redis-cli -p 9001 -h 127.0.0.1 GRAPH.QUERY cord19medical "MATCH (e:entity)-[r]->(t:entity) RETURN count(r) as edge_count"

检查 API 响应:#

 curl -i -H "Content-Type: application/json" -X POST -d '{"search":"How does temperature and humidity affect the transmission of 2019-nCoV"}'
 http://localhost:8080/gsearch

详细说明#

虽然 RedisGears 允许部署和运行诸如 spacyBERT transformers 之类的机器学习库,但上述解决方案采用了更简单的方法:

 gb = GB('KeysReader')
 gb.filter(filter_language)
 gb.flatmap(parse_paragraphs)
 gb.map(spellcheck_sentences)
 gb.foreach(save_sentences)
 gb.count()
 gb.register('paragraphs:*',keyTypes=['string','hash'], mode="async_local")

这是整体流水线:这 7 行代码允许您在分布式集群或单机上使用所有可用的 CPU 运行逻辑 - 在需要扩展到超过 1000 个节点之前无需更改。我使用针对命名空间 paragraphs 注册的 KeysReader 来处理所有字符串或哈希。我的流水线需要运行在异步模式下。对于数据科学家来说,我建议先使用 gb.run 来确保齿轮(gears)功能正常工作并在批量模式下运行,然后再将其更改为 register - 以捕获新数据。默认情况下,函数将返回输出,因此需要使用 count() - 以防止将整个数据集(对于 Cord19 为 90GB)取回到发出命令的机器。

整体预处理非常直接 - 完整代码在此。

注意事项

  1. 1.节点进程只能本地保存 - 我们不移动数据,任何您想保存的内容都应该带有 hashtag,例如添加到 processed_docs 集合中:
 execute('SADD','processed_docs_{%s}' % hashtag(),article_id)

2. 将外部库加载到计算线程中,例如 symspell 需要额外的字典,并且需要两个步骤来加载

 """
 load symspell and relevant dictionaries
 """
 sym_spell=None

 def load_symspell():
  import pkg_resources
  from symspellpy import SymSpell, Verbosity
  sym_spell = SymSpell(max_dictionary_edit_distance=1, prefix_length=7)
  dictionary_path = pkg_resources.resource_filename(
      "symspellpy", "frequency_dictionary_en_82_765.txt")
  bigram_path = pkg_resources.resource_filename(
      "symspellpy", "frequency_bigramdictionary_en_243_342.txt")
  # term_index is the column of the term and count_index is the
  # column of the term frequency
  sym_spell.load_dictionary(dictionary_path, term_index=0, count_index=1)
  sym_spell.load_bigram_dictionary(bigram_path, term_index=0, count_index=2)
  return sym_spell

3. Scispacy 是一个很棒的库和数据科学工具,但在多次尝试部署它之后,我最终阅读了 UMLS Methathesaurus 的数据模型文档,并决定直接从 UMLS 数据构建 Aho-Corasick 自动机。(MRXW_ENG.RRF 包含映射到 CUI 的所有英文术语形式)。Aho-Corasick 使我能够将输入的句子匹配成节点对(来自医学词典的概念),并将句子表示为图中的边,Gears 相关代码很简单

 bg = GearsBuilder('KeysReader')
 bg.foreach(process_item)
 bg.count()
 bg.register('sentence:*',  mode="async_local",onRegistered=OnRegisteredAutomata)

OnRegisteredAutomata 的表现将类似于上面的 symspell 示例,但它会下载预构建的 Aho-Corasick 自动机 (30Mb)。Aho-Corasick 是一个非常快速的匹配器,即使在普通笔记本电脑上也能达到每秒 >900 Mb 的文本匹配速度,RedisGears 集群利用可用的 CPU 和内存,实现了数据和 ML 模型以及匹配的非常平滑的分布。完整匹配器代码

匹配器的输出:节点和边是使用另一种 RedisGears 模式 rgsync 的候选,通过 rgsync,您可以快速写入 Redis,然后 RedisGears 会使用 RedisStreams 将数据复制到较慢的存储中。但我决定使用流并手动构建 RedisGraph 数据库的填充过程,这将是下一篇博文的重点。

匹配器的输出:节点和边是使用另一种 RedisGears 模式 rgsync 的候选,通过 rgsync,您可以快速写入 Redis,然后 RedisGears 会使用 RedisStreams 将数据复制到较慢的存储中。本次演示使用流并填充 RedisGraph 数据库,计算每个节点和边的排名。

行动号召#

我们获取了 JSON 格式的 OCR 扫描数据,并将其转换为知识图谱,演示了如何使用基于统一医学语言系统 (Unified Medical Language System) 的传统语义网络/OWL/元同义词库技术。Redis 生态系统为数据科学社区提供了很多东西,它可以成为 Kaggle notebook、ML 框架的核心,并使数据的部署和分发更加愉快。我们行业的成功取决于我们的工具如何协同工作——无论是工程、数据科学、机器学习,还是组织或架构层面的工具。

在 RedisLabs 和社区的协作下,完整的流水线代码可通过 https://github.com/applied-knowledge-systems/the-pattern-platform 获取。如果您想在本地尝试,可以在代码库的根目录下找到 Docker 启动脚本以及简短的快速入门指南。欢迎 PR 和建议。该项目的总体目标是让其他人在此基础上构建更有趣的流水线。

参考资料#