Go语言实现大模型分词器tokenizer

文章目录

  • 前言
  • 核心结构体定义
  • 构造函数
  • 文本初始处理
  • 组词
  • 构建词组索引
  • 训练数据
  • 编码
  • 解码
  • 打印状态信息
  • 运行效果
  • 总结

前言

大模型的tokenizer用于将原始文本输入转化为模型可处理的输入形式。tokenizer将文本分割成单词、子词或字符,并将其编码为数字表示。大模型的tokenizer通常基于词表进行编码,使用词嵌入将单词映射为向量表示。tokenizer还可以将输入文本进行填充和截断,以确保所有输入序列的长度一致,以便于模型的批量处理。

这篇博客的tokenizer分析器使用纯粹的Go语言标准库实现,不借用任何其它第三方库。用轮子是生活,造轮子是信仰。

核心结构体定义

type BytePairEncoder struct {wsToken  stringunkToken string// k: word, v: tokenswordToken map[string]*[]string// k: word, v: countwordCount map[string]int// k: token, v: counttokenCount map[string]int// k: id, v: tokenidToken map[int]string// k: token, v: idtokenId map[string]int
}

构造函数

func DefaultBytePairEncoder() *BytePairEncoder {return NewBytePairEncoder("_", " ")
}func NewBytePairEncoder(wsToken, unkToken string) *BytePairEncoder {return &BytePairEncoder{wsToken:    wsToken,unkToken:   unkToken,wordToken:  make(map[string]*[]string),wordCount:  make(map[string]int),tokenCount: make(map[string]int),idToken:   make(map[int]string),tokenId:   make(map[string]int),}
}

文本初始处理

func (e *BytePairEncoder) wordToTokens(word string) *[]string {parts := []rune(word)n := len(parts)res := make([]string, n)for i := 0; i < n; i++ {token := string(parts[i])e.tokenCount[token]++res[i] = token}return &res
}func (e *BytePairEncoder) preprocess(text string) []string {text = strings.TrimSpace(text)return strings.Fields(text)
}func (e *BytePairEncoder) processWord(word string) {e.wordToken[word] = e.wordToTokens(word)e.wordCount[word]++
}func (e *BytePairEncoder) initState(text string) {words := e.preprocess(text)for _, word := range words {e.processWord(e.wsToken + word)}
}

组词

func (e *BytePairEncoder) mergePair() {// k: token, v: countm := make(map[string]int)for word, tokens := range e.wordToken {n := len(*tokens) - 1for i := 0; i < n; i++ {m[(*tokens)[i]+(*tokens)[i+1]] += e.wordCount[word]}}maxToken := ""maxCount := 0for k, v := range m {if v > maxCount {maxToken = kmaxCount = v}}if maxCount < 2 {return}e.tokenCount[maxToken] = maxCountfor _, tokens := range e.wordToken {n := len(*tokens) - 1for i := 0; i < n; i++ {if (*tokens)[i]+(*tokens)[i+1] == maxToken {e.tokenCount[(*tokens)[i]]--e.tokenCount[(*tokens)[i+1]]--post := (*tokens)[i+1:]post[0] = maxToken*tokens = (*tokens)[:i]*tokens = append((*tokens), post...)*tokens = (*tokens)[:len(*tokens)]i--n -= 2}}}
}func (e *BytePairEncoder) merge(steps int) {for i := 0; i < steps; i++ {e.mergePair()}
}

构建词组索引

func (e *BytePairEncoder) buildIndex() {e.tokenId[e.unkToken] = 0e.idToken[0] = e.unkTokeni := 1for token := range e.tokenCount {e.tokenId[token] = ie.idToken[i] = tokeni++}
}

训练数据

func (e *BytePairEncoder) Train(text string, steps int) {e.initState(text)e.merge(steps)e.buildIndex()
}

编码

func (e *BytePairEncoder) segment(words []string) []int {res := make([]int, 0)for _, word := range words {parts := []rune(word)NEXT:for i := len(parts); i >= 1; i-- {if code, ok := e.tokenId[string(parts[:i])]; ok {parts = parts[i:]res = append(res, code)goto NEXT}}if len(parts) == 0 {continue}code := e.tokenId[string(parts[0])]res = append(res, code)parts = parts[1:]if len(parts) != 0 {goto NEXT}}return res
}func (e *BytePairEncoder) Encode(text string) []int {words := e.preprocess(text)return e.segment(words)
}

解码

func (e *BytePairEncoder) Decode(codes []int) []string {res := make([]string, 0)for _, code := range codes {res = append(res, e.idToken[code])}return res
}

打印状态信息

func (e *BytePairEncoder) Dump() {fmt.Println("===== dump state ======")fmt.Println("===> dump wordToken <===")for word, tokens := range e.wordToken {fmt.Println(word, "=>", *tokens)}fmt.Println()fmt.Println("===> dump wordcnt <===")for word, count := range e.wordCount {fmt.Println(word, "=>", count)}fmt.Println()fmt.Println("===> dump tokenCount <===")for token, count := range e.tokenCount {fmt.Println(token, "=>", count)}fmt.Println()fmt.Println("===> dump idTokens <===")for code, token := range e.idToken {fmt.Println(code, "=>", token)}fmt.Println()fmt.Println("===> dump tokenIds <===")for token, code := range e.tokenId {fmt.Println(token, "=>", code)}fmt.Println()
}

运行效果

我们的tokenizer已经开发完毕,现在可以运行我们的tokenizer,看看是否能达到我们想要的效果

package mainimport ("fmt""os""tokenizer"
)func main() {trainData, err := os.ReadFile("./data.txt")if err != nil {panic(err)}steps := 50enc := tokenizer.DefaultBytePairEncoder()enc.Train(string(trainData), steps)input := "提取数据特征进行预测"codes := enc.Encode(input)tokens := enc.Decode(codes)fmt.Println(codes)fmt.Println(tokens)
}

输入数据集
data.txt

机器学习、深度学习和强化学习是人工智能领域中的三个重要技术方向。以下是它们的区别:
机器学习:机器学习是一种通过从数据中自动学习模式和规律来进行预测和决策的方法。它涉及到使用算法和统计模型,从数据中提取特征并进行模型训练,进而对未知数据进行预测或分类。机器学习的重点在于自动学习和泛化能力,它不需要明确的指令或规则来执行任务,而是通过数据和经验来改善性能。
深度学习:深度学习是机器学习的一个分支,它使用包含多个神经网络层的深度神经网络进行学习和预测。深度学习模型通过层层堆叠的方式,从原始数据中学习到多个抽象层次的特征表示。深度学习的优势在于可以自动提取复杂的特征,并通过大规模数据的训练来优化模型性能。它被广泛应用于计算机视觉、自然语言处理和语音识别等领域。
强化学习:强化学习是一种机器学习的方法,旨在让机器学习从环境中的交互中通过试错来改善性能。它通过不断与环境进行交互,观察环境状态并执行动作,然后从环境的反馈中学习如何在给定环境中做出最优的决策。强化学习的目标是通过学习最优的策略来最大化累积奖励。强化学习在游戏、机器人控制和优化问题等领域有着广泛应用。
总的来说,机器学习是从数据中学习模式和规律,深度学习是机器学习的一种方法,使用深度神经网络来提取复杂的特征表示,强化学习是通过试错学习从环境中改善性能。

运行效果
在这里插入图片描述

可以根据情况使用Dump函数打印状态信息查看更多细节

总结

恭喜你已经制作了一个属于自己的tokenizer分词器,我们实现的相对粗糙一点,但是对于初学者是难得的实战项目,麻雀虽小,五脏俱全。

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

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

相关文章

【广州华锐视点】VR模拟法庭审判实训,零距离感受庭审全过程

随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术已经逐渐渗透到各个领域&#xff0c;为人们提供了全新的体验方式。在法律领域&#xff0c;VR技术的应用也日益受到关注。近年来&#xff0c;越来越多的法学院和培训机构开始尝试将VR技术引入模拟法庭实践…

电商数据采集中如何采集1688平台商品详情SKU数据

一、背景介绍 1688.com是阿里旗下国内最大的B2B批发采购平台&#xff0c;1688分销客是依托此平台的官方营销平台&#xff0c;通过此平台API接口的接入推广平台商家的商品&#xff0c;按照商品成交金额的一定比例获得佣金。可以调用1688平台上的商品详情&#xff0c;SKU数据&…

社区内涝积水监测系统作用,改善社区积水

随着社区化进程的加速&#xff0c;社区基础设施的重要性日益凸显。在这个背景下&#xff0c;社区生命线和内涝积水监测系统成为了关注的焦点。它们在维护社区安全&#xff0c;特别是在应对暴雨等极端天气条件下&#xff0c;发挥着至关重要的作用。 WITBEE万宾时刻关注社区内涝积…

PCL 最小二乘拟合圆柱(C++详细过程版)

目录 一、算法原理1、算法简介2、参考文献二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法简介 圆柱拟合步骤主要包括两步: 一是确定柱面模型参数初始值…

关于大模型在文本分类上的尝试

文章目录 前言所做的尝试总结前言 总共25个类别,在BERT上的效果是48%,数据存在不平衡的情况,训练数据分布如下: 训练数据不多,4000左右 所做的尝试 1、基于 Qwen-14b-base 做Lora SFT,Loss忘记记录 准确率在68%左右 Lora配置 class LoraArguments:lora_r: int = 64…

【JavaEE初阶】volatile 关键字、wait 和 notify

目录 一、volatile 关键字 1、volatile 能保证内存可见性 2、volatile 不保证原子性 二、wait 和 notify 1、wait()方法 2、notify()方法 3、notifyAll()方法 4、wait 和 sleep 的对比 一、volatile 关键字 1、volatile 能保证内存可见性 我们前面的线程安全文章中&…

Docker安装可视化工具Portainer

目录 Portainer简介 Portainer安装 Portainer简介 Portainer是一款开源的容器管理平台&#xff0c;支持多种容器技术&#xff0c;如Docker、Kubernetes和Swarm等。它提供了一个易于使用的Web UI界面&#xff0c;可用于管理和监控容器和集群。Portainer旨在使容器管理更加简单…

前端三大MV*模式:MVC、mvvm、mvp模式介绍

MVC&#xff08;同步通信为主&#xff09;&#xff1a;Model、View、Controller MVP(异步通信为主)&#xff1a;Model、View、Presenter MVVM(异步通信为主)&#xff1a;Model、View、ViewModel mvc模式介绍 MVC&#xff08;Model–View–Controller&#xff09;模式是软件…

Elk:filebeat 日志收集工具和logstash

Elk:filebeat 日志收集工具和logstash Filebeat是一个轻量级的日志手机工具,所使用的系统资源比logstash部署和启动时使用的资源要小得多 Filebeat可以在非java环境使用&#xff0c;他可以代理logstash在非java环境上收集日志 缺点 Filebeat无法实现数据的过滤,一般是结合l…

Direct local .aar file dependencies are not supported when building an AAR.

Direct local .aar file dependencies are not supported when building an AAR. 问题描述&#xff1a;打debug包没有问题&#xff0c;但是打release包(无论是apk还是aar包)时会报错“Direct local .aar file dependencies are not supported when building an AAR.” 原因&a…

【路径规划】move_base、路径规划算法、局部避障算法介绍

资料整理供个人学习使用。 文章目录 一、move_base1、move_base 包内容2、move_base 参数解析1. move_base 参数2. 全局代价地图参数3. 局部代价地图参数4. 全局规划器参数5. 局部规划器参数 二、路径规划1、Dijkstra2、最佳优先搜索3、A*4、A* 和 Dijkstra 比较 三、局部避障1…

k8s部署es和skywalking

使用k8s部署es和skywalking skywalking介绍 skywalking架构 整个架构&#xff0c;分成上、下、左、右四部分&#xff1a; 上部分 Agent &#xff1a;负责从应用中&#xff0c;收集链路信息&#xff0c;发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等…

【腾讯云 HAI域探秘】使用高性能应用服务HAI快速开发一款赛博朋克风拼图游戏,化繁从简,低成本进入人工智能时代。

前言 人工智能&#xff08;AI&#xff09;是当今科技领域的热门话题&#xff0c;尤其是自然语言处理&#xff08;NLP&#xff09;技术&#xff0c;它可以让机器理解和生成自然语言。随着大型语言模型&#xff08;LLM&#xff09;的发展&#xff0c;如 GPT-3、DALL-E 等&#xf…

蓝桥杯每日一题2023.11.29

题目描述 #include <stdio.h> #include <string.h>void StringInGrid(int width, int height, const char* s) {int i,k;char buf[1000];strcpy(buf, s);if(strlen(s)>width-2) buf[width-2]0;printf("");for(i0;i<width-2;i) printf("-"…

KT1404C语音芯片为什么用着用着,声音就变大了,发指令设置音量?

一、问题简介 有客户反馈&#xff0c;使用KT404C语音芯片&#xff0c;每次主板上电的时候&#xff0c;都会发指令将音量设置为20级&#xff0c;但是实际到使用现场&#xff0c;就会有终端的客人反馈&#xff0c;机器的音量变大了&#xff0c;这个是什么情况呢&#xff0c;该如…

java:IDEA中Maven常用操作

文章目录 背景1、Reload All Maven Projects:2、Generate Sources and Update Folders For All Projects:3、Download Sources and/or Documentation:4、Add Maven Projects5、Run Maven Build6、Execute Maven Goal7、Toggle Offline Mode8、Toggle Skip Tests Mode9、Collaps…

网络通信概述

文章目录 IP地址端口号协议三要素作用 五元组协议分层OSI七层模型TCP/IP 五层模型应用层传输层网络层数据链路层物理层 封装和分用发送方 - 封装中间转发接收方 - 分用 一般认为计算机网络就是利用通信线路和通信设备将地理上分散的、具有独立功能的多个计算机系统按不同的形式…

修复 Apache Kafka 中的远程代码执行漏洞CVE-2023-25194

文章目录 前言一、Log4Shell connection二、DisclosureUpdates, mitigations 前言 Possible RCE and denial-of-service issue discovered in Kafka Connect 在 Kafka Connect 中发现可能的 RCE 和拒绝服务问题。 更新 阿帕奇软件基金会 (ASF) 已解决了一个漏洞&#xff0c;…

【深度学习实验】图像处理(三):PIL——自定义图像数据增强操作(随机遮挡、擦除、线性混合)

文章目录 一、实验介绍二、实验环境1. 配置虚拟环境2. 库版本介绍 三、实验内容0. 导入必要的库1. PIL基础操作2. Cutout&#xff08;遮挡&#xff09;2.1 原理2.2 实现2.3 效果展示 3. Random Erasing&#xff08;随机擦除&#xff09;3.1 原理3.2 实现3.3 效果展示 4. Mixup&…

健身房服务预约会员管理系统小程序效果怎样

健身房是很多人锻炼的主要场所之一&#xff0c;各地城区都有大量品牌&#xff0c;主要以同城客户为主&#xff0c;具备较强的客户管理和门店运营属性 &#xff0c;面对当今互联网环境&#xff0c;需要商家进一步管理赋能。 那么通过【雨科】平台搭建健身房管理系统能帮助商家实…