阅读medusa技术总结

medusa简单实现和transformer的seq2seq的实现区别

medusa代码简单如下

import tensorflow as tf
from tensorflow.keras import layers, Model

# 基础 Transformer 模型
class SimpleTransformer(Model):
    def __init__(self, vocab_size, hidden_dim, num_heads, num_layers):
        super(SimpleTransformer, self).__init__()
        self.embedding = layers.Embedding(vocab_size, hidden_dim)
        self.transformer = [
            layers.MultiHeadAttention(num_heads=num_heads, key_dim=hidden_dim) for _ in range(num_layers)
        ]
        self.fc_out = layers.Dense(vocab_size)  # 最后的语言模型输出层

    def call(self, inputs):
        x = self.embedding(inputs)
        for mha in self.transformer:
            x = mha(x, x)
        return self.fc_out(x)

# 定义带有多个解码头的 MEDUSA 模型
class MedusaTransformer(Model):
    def __init__(self, base_model, num_heads, hidden_dim, vocab_size):
        super(MedusaTransformer, self).__init__()
        self.base_model = base_model  # 基础的 Transformer 模型
        self.medusa_heads = [  # 定义多个解码头
            layers.Dense(hidden_dim, activation='swish') for _ in range(num_heads)
        ]
        self.output_heads = [  # 每个解码头的输出层
            layers.Dense(vocab_size) for _ in range(num_heads)
        ]

    def call(self, inputs):
        # 获取基础模型的最后隐藏状态
        hidden_states = self.base_model(inputs)

        # 使用多个解码头并行生成多个候选词的分布
        outputs = [output_head(medusa_head(hidden_states)) for medusa_head, output_head in zip(self.medusa_heads, self.output_heads)]
        return outputs

# 初始化模型
vocab_size = 10000
hidden_dim = 512
num_heads = 8
num_layers = 6
base_model = SimpleTransformer(vocab_size, hidden_dim, num_heads, num_layers)

# 添加 3 个解码头
medusa_model = MedusaTransformer(base_model, num_heads=3, hidden_dim=hidden_dim, vocab_size=vocab_size)

# 示例输入
input_tokens = tf.constant([[1, 2, 3]])  # 示例输入

# 使用 MEDUSA 模型进行推理
outputs = medusa_model(input_tokens)

print("Medusa Outputs:", outputs)

seq2seq如下

import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleTransformer(nn.Module):
    def __init__(self, vocab_size, hidden_dim, num_heads, num_layers):
        super(SimpleTransformer, self).__init__()
        # 词嵌入层
        self.embedding = nn.Embedding(vocab_size, hidden_dim)
        # Transformer 编码器层
        self.transformer = nn.Transformer(
            d_model=hidden_dim,
            nhead=num_heads,
            num_encoder_layers=num_layers,
            num_decoder_layers=num_layers
        )
        # 语言模型输出层
        self.fc_out = nn.Linear(hidden_dim, vocab_size)

    def forward(self, src, tgt):
        # 进行嵌入
        src_embedding = self.embedding(src)
        tgt_embedding = self.embedding(tgt)
        # 通过 Transformer 模型
        transformer_output = self.transformer(src_embedding, tgt_embedding)
        # 输出词的分布
        output = self.fc_out(transformer_output)
        return output

def generate_text(model, tokenizer, start_token, max_length=20):
    # 将起始 token 转化为输入张量
    input_tokens = torch.tensor([start_token]).unsqueeze(0)  # Shape: (1, 1)
    model.eval()  # 设置模型为评估模式

    for _ in range(max_length):
        # 使用模型进行前向传播,预测下一个 token
        output = model(input_tokens, input_tokens)
        next_token_logits = output[:, -1, :]  # 获取最后一个时间步的输出
        next_token_probs = F.softmax(next_token_logits, dim=-1)
        next_token = torch.argmax(next_token_probs, dim=-1).item()  # 选择概率最大的词

        # 将下一个 token 添加到输入序列中
        input_tokens = torch.cat([input_tokens, torch.tensor([[next_token]])], dim=1)

        # 如果生成结束符,停止生成
        if next_token == tokenizer['<eos>']:
            break

    # 返回生成的词序列
    generated_text = [tokenizer[i] for i in input_tokens.squeeze().tolist()]
    return " ".join(generated_text)

# 模型和词典初始化
vocab_size = 10000  # 假设词汇表大小为 10000
hidden_dim = 512
num_heads = 8
num_layers = 6
model = SimpleTransformer(vocab_size, hidden_dim, num_heads, num_layers)

# 示例的 tokenizer 和起始 token
tokenizer = {i: f"word{i}" for i in range(vocab_size)}
tokenizer['<eos>'] = vocab_size - 1  # 假设词汇表最后一个是结束符
start_token = 0  # 假设 0 号词是起始 token

# 生成文本
generated_text = generate_text(model, tokenizer, start_token)
print("Generated Text:", generated_text)

昨天我看了medusa这个概论并且大致看了源代码

MEDUSA不同于传统的transformer采取的自回归生成方法,采用了一种类似informer的策略,使用多个解码头来并行生成多个后续词的候选项,这样就不必严格按照逐词顺序生成。

MEDUSA 利用了树状注意力机制(tree-based attention)来构建多个解码头,解码头里面有多个生成的候选词,并在每一步解码中同时使用笛卡尔积进行组合并验证这些候选词。验证方法:MEDUSA 引入了一种叫做典型接受(Typical Acceptance)的方案,用于评估候选序列的合理性。这个方案主要是通过设定一个基于熵的阈值,来选择哪些候选词被接受。

这样,通过并行处理,MEDUSA 大大减少了所需的解码步骤数量。

添加 MEDUSA 解码头:

在 LM Head 之后,添加多个解码头(如 Medusa Head 1, Medusa Head 2, ...),每个解码头都是一个用于预测不同位置后续词的前馈网络层(Feed-Forward Layer)。解码头的数量可以根据需要设定,通常为 3-5 个。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Netty笔记10-Netty参数调优

文章目录 一、CONNECT_TIMEOUT_MILLISCONNECT_TIMEOUT_MILLIS设置为1秒超时CONNECT_TIMEOUT_MILLIS设置为5秒超时注意事项 二、SO_BACKLOG代码示例注意事项 三、ulimit -n(文件描述符)设置文件描述符限制在注意事项 四、TCP_NODELAY使用 TCP_NODELAY 的场景注意事项 五、SO_SND…

JavaWeb--纯小白笔记03:servlet入门---动态网页的创建

笔记&#xff1a;index.html在tomcat中为默认的名字&#xff0c;html里面的语法不严谨。改配置文件要小心&#xff0c;不然容易删掉其他 Servlet&#xff1a;服务器端小程序&#xff0c;写动态网页需要用Servlet&#xff0c;普通的java类通过继承HttpServlet&#xff0c;可以响…

【重学 MySQL】三十一、字符串函数

【重学 MySQL】三十一、字符串函数 函数名称用法描述ASCII(S)返回字符串S中的第一个字符的ASCII码值CHAR_LENGTH(s)返回字符串s的字符数&#xff0c;与CHARACTER_LENGTH(s)相同LENGTH(s)返回字符串s的字节数&#xff0c;和字符集有关CONCAT(s1,s2,…,sn)连接s1,s2,…,sn为一个字…

Docker + Win 10 学习记录

下载Docker Release notes | Docker Docs 推荐使用4.33版本&#xff0c;最新的Docker版本在win10 22H2无法安装。需要升级到win11. 查看Win10版本是否与最新版的Docker兼容 运行 win R&#xff0c; 然后输入winver 如果你的Docker版本无法在当前的win10安装&#xff0c;请更…

828华为云征文|华为云Flexus云服务器X实例部署Xnote笔记应用

828华为云征文&#xff5c;华为云Flexus云服务器X实例部署Xnote笔记应用 前言一、Flexus云服务器X实例介绍1.1 Flexus云服务器X实例简介1.2 Flexus云服务器X实例特点1.3 Flexus云服务器X实例使用场景 二、Note Mark 介绍2.1 Xnote简介2.2 Xnote特点2.3 主要使用场景 三、本次实…

豆包Python SDK接入流程

模型与价格 豆包的模型介绍可以看豆包大模型介绍&#xff0c;模型价格可以看豆包定价文档里的“模型推理” - “大语言模型” - “字节跳动”部分。 推荐使用以下模型&#xff1a; Doubao-lite-32k&#xff1a;每百万 token 的输入价格为 0.3 元&#xff0c;输出价格为 0.6 元…

JavaEE: 深入探索TCP网络编程的奇妙世界(六)

文章目录 TCP核心机制TCP核心机制九: 面向字节流TCP核心机制十: 异常处理 小小的补充(URG 和 PSH)~TCP小结TCP/UDP 对比用UDP实现可靠传输(经典面试题) 结尾 TCP核心机制 上一篇文章JavaEE: 深入探索TCP网络编程的奇妙世界(五) 书接上文~ TCP核心机制九: 面向字节流 TCP是面…

桶排序和计数排序(非比较排序算法)

桶排序 桶排序是一种基于分配的排序算法&#xff0c;特别适合用来排序均匀分布的数据。它的基本思想是将输入的数据分到有限数量的桶里&#xff0c;然后对每个桶内的数据分别进行排序&#xff0c;最后再将各个桶内的数据合并得到最终的排序结果。(通常用于浮点数&#xff0c;因…

Linux:RPM软件包管理以及yum软件包仓库

挂载光驱设备 RPM软件包管理 RPM软件包简介 区分软件名和软件包名 软件名&#xff1a;firefox 软件包名&#xff1a;firefox-52.7.0-1.el7.centos.x86_64.rpm 查询软件信息 查询软件&#xff08;参数为软件名&#xff09; ]# rpm -qa #当前系统中所有已安装的软件包 ]# r…

WebGL颜色与纹理

WEBGL中的着色器变量包括以下种类&#xff1a; 属性变量&#xff08;Attribute Variables&#xff09;&#xff1a;这些变量用于接收从应用程序中传递的顶点数据&#xff0c;比如顶点位置和颜色&#xff0c;是只读的不可修改。统一变量&#xff08;Uniform Variables&#xff…

AI浪潮新崛起:借助AI+实景/视频直播创新魅力,开启无人自动直播新时代!

AI浪潮新崛起&#xff1a;借助AI实景/视频直播创新魅力&#xff0c;开启无人自动直播新时代&#xff01; 在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;已不再仅仅是科幻电影中的桥段&#xff0c;它正以不可阻挡之势渗透到我们生活的方方面面&#xff…

力扣718-最长重复子数组(Java详细题解)

题目链接&#xff1a;718. 最长重复子数组 - 力扣&#xff08;LeetCode&#xff09; 前情提要&#xff1a; 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 dp五部曲。 1.确定dp数组和i下标的含义。 2.确定递推公式。 3.dp初始化。 4.确定dp的遍历顺序。 5…

【编程底层原理】Java常用读写锁的使用和原理

一、引言 在Java的并发世界中&#xff0c;合理地管理对共享资源的访问是至关重要的。读写锁&#xff08;ReadWriteLock&#xff09;正是一种能让多个线程同时读取共享资源&#xff0c;而写入资源时需要独占访问的同步工具。本文将带你了解读写锁的使用方法、原理以及它如何提高…

这8款AI论文工具帮你一键搞定!ai论文一键生成任务书

在当今学术研究和论文写作领域&#xff0c;AI技术的应用已经成为一种趋势。通过智能算法和大数据分析&#xff0c;AI工具能够帮助学者和学生提高写作效率、优化内容结构&#xff0c;并确保论文的原创性和质量。以下是8款值得推荐的AI论文工具&#xff0c;其中特别推荐千笔-AIPa…

选择排序(C语言实现)

目录 1.基本思想 2.代码实现 代码思路 代码实现 代码测试 3.复杂度分析 1&#xff09;时间复杂度 2&#xff09;空间复杂度 4.特性总结 1.基本思想 选择排序是一种简单直观的比较排序算法。该算法的基本思想是在每一轮中选出当前未排序部分的最小&#xff08;或最大&a…

通过 LabVIEW 正则表达式读取数值(整数或小数)

在LabVIEW开发中&#xff0c;字符串处理是一个非常常见的需求&#xff0c;尤其是在处理包含复杂格式的数字时。本文通过一个具体的例子来说明如何利用 Match Regular Expression Function 和 Match Pattern Function 读取并解析字符串中的数字&#xff0c;并重点探讨这两个函数…

日期和时间类【Date】【Calendar日历类】【LocalDate】Date-Time API详解

我们先来介绍一下与时间相关的基础知识。 GMT - 格林尼治标准时间&#xff08;Greenwich Mean Time&#xff09;&#xff0c;简称GMT&#xff0c;实际上与世界时UT&#xff08;universal time &#xff09;基本一致。 UTC - 协调世界时&#xff08;Universal Time Coordinated&…

matlab恢复默认窗口布局

1.点击主页&#xff0c;选择布局 2.选择默认&#xff0c;即可恢复到默认的窗口布局

Linux系统上搭建Vulhub靶场

Linux系统上搭建Vulhub靶场 ​vulhub​ 是一个开源的漏洞靶场&#xff0c;它提供了各种易受攻击的服务和应用程序&#xff0c;供安全研究人员和学习者测试和练习。要在 Linux 系统上安装和运行 vulhub​&#xff0c;可以按照以下步骤进行&#xff1a; 1. 安装 Docker 和 Docke…

C#软键盘设计字母数字按键处理相关事件函数

应用场景&#xff1a;便携式设备和检测设备等小型设备经常使用触摸屏来代替键盘鼠标的使用&#xff0c;因此在查询和输入界面的文本或者数字输入控件中使用软件盘来代替真正键盘的输入。 软键盘界面&#xff1a;软键盘界面实质上就是一个普通的窗体上面摆放了很多图片按钮&…