cyberyang
type: channel
link: https://cyberyang.com/
description: 更新知识地图，拓展认知边界
items: 铭刻者
items: 大模型RAG语言交互游戏
items: Ubuntu 分区方案
items: WSL玄学bug之SSH连接找不到nvidia-smi
items: VSCode配置MacTeX
items: TensorRT量化加速yolov8目标检测
items: TensorRT部署yolov8目标检测任务
items: TensorRT加速MNIST手写数字识别
items: VSCode配置C++开发
items: 基于Transformer网络的中译英翻译器

铭刻者
type: item
date: 2025-12-01T20:28:00+08:00
description: Gemini 3 Pro 生成内容短篇小说：《铭刻者》一林拓站在“审判之眼”观测站的悬窗前，手里那杯合成咖啡已经冷透了。窗外不是星空，而是一片纯粹的、令人窒息的漆黑。那是编号为 X-902 的原初黑洞。它只有月球大小，视界直径约三千五百公里，却拥有五百个太阳的质量。它像是一颗宇宙肌肤上坏死的黑痣，静静地悬浮在半人马座旋臂的荒原上。“这一凿下去，半个恒星系的能量就没了。”身后的声音带着金属质感的颤动，是这里的首席操作员雷迪亚兹。“这是必要的消耗。”林拓的声音很轻，却透着一种像岩石般冷硬的固执，“物质会衰变，质子会瓦解，连光都会在膨胀的宇宙中稀释成无线电波。只有引力波的涟漪，能够在时空的结构中永存。”这是“文明墓碑”计划的最后阶段。人类文明已经进入了黄昏。不是因为战争，也不是因为资源枯竭，而是因为宇宙本身的“老死”。熵增就像一种慢性毒药，渗入了星系的每一个角落。人类决定在灭绝前做最后一件事：将人类的历史、科学、艺术，编码成高强度的引力波束，轰击向 X-902 黑洞的事件视界。根据广义相对论，对于远处的观察者来说，时间在引力场极强的地方会无限变慢。坠入视界的信息，永远不会真正“掉进去”，而是会被无限冻结在边缘。这颗黑洞，将成为人类文明永恒的硬盘，直到宇宙热寂的尽头。“充能进度 99%。”雷迪亚兹汇报道，“准备锁定视界‘画布’。”二屏幕上展开了视界表面的模拟网格图。按照理论，那应该是一面完美的镜子，平滑、死寂，连光都逃不脱它的引力囚笼。为了确保信息的可读性，他们必须找到一块绝对平滑、没有被之前的物质吸积所扰动的“空白区域”。“正在进行视界表面高精度扫描……启用引力透镜模式。”全息投影被放大了。在原本应该是绝对光滑的视界表面，出现了一些极微小的、如果不使用引力透镜放大一亿倍绝对无法察觉的……褶皱。“那是引力波留下的‘软毛’。”林拓凑近了屏幕，呼吸凝滞了。那不是自然的产物。自然的物质坠落是杂乱无章的噪点，而这些褶皱，有着惊人的几何规律。它们像地层一样层层叠叠，每一层都代表着一段漫长得令人绝望的地质年代。“扫描整个视界。”林拓命令道，声音干涩。结果出来了。没有空白。没有哪怕一平方微米的空白。整个 X-902 黑洞的视界表面，密密麻麻地覆盖着这种褶皱。林拓突然感到一种巨大的、难以名状的荒谬感。人类以为自己是孤独的朝圣者，耗尽最后的资源，长途跋涉来到这块宇宙尽头的丰碑前，想要刻下“到此一游”。却发现，这块丰碑上早已被涂写得没有一丝缝隙。这是一个拥挤的墓地。每一个能在宇宙规律面前挣扎到最后的文明，都想到了同一个主意：把记忆留给黑洞。三观测站陷入了死一般的寂静。“能分析出源头吗？”雷迪亚兹的手指在颤抖。“太多了……”林拓看着那些数据流，就像看着一场跨越百亿年的暴雨，“最上面这一层，虽然刻录点在这里，但解码出的星图标尺显示，它们来自 M31——仙女座大星系。”“仙女座？”雷迪亚兹惊愕地抬起头，“那是 254 万光年外。它们为什么跑这么远？它们家里没有黑洞吗？”“因为家里不安全。”林拓看着那片黑暗，仿佛洞穿了数百万光年的虚空，“仙女座比银河系更大、更亮。那里一定是高等文明争夺的中心，是猎手密布的战场。只有把备份藏到银河系这个偏僻的、荒凉的‘乡下’，藏在这颗毫不起眼的小黑洞上，才有一丝留存的希望。”林拓闭上了眼睛。他在脑海中想象着那个仙女座的文明。它们可能正在面临灭顶之灾——也许是二向箔的吞噬，也许是光速慢化的囚笼。在毁灭的前夜，它们派出了一支绝望的远征队，跨越两百多万光年的死寂虚空，只为了在这里留下一份备份。这种跨越时空的共鸣，比任何接触都更加震撼，也更加悲凉。宇宙不是童话，宇宙是一座这就着火的图书馆。所有的文明都在疯狂地把书往唯一的防火保险柜里塞，没人顾得上礼貌，也没人顾得上顺序。四“长官，警报！”刺耳的红光打断了哀悼。深空雷达显示，在 X-902 的航线前方，一团无形的力场正像扫帚一样横扫过虚空，将沿途的星际尘埃和小行星瞬间粉碎、推开。“那是什么？”“是清道夫。”林拓瞬间明白了一切，“怪不得这颗黑洞这么干净，怪不得这里是荒原。有一个古老的文明在维护它，它们定期清理航道，确保视界不被杂质污染。”“它将在十分钟后扫过我们。”雷迪亚兹脸色苍白，“我们会被当成灰尘扫掉。”留给人类的时间不多了。“还要刻吗？”雷迪亚兹回头，看着屏幕上密密麻麻的褶皱，“为了写下人类的名字，我们需要抹去另一个文明存在的痕迹。也许那个被覆盖的，就是仙女座那个文明最后的备份。”覆盖它们，我们就成了毁灭历史的野蛮人。不覆盖，人类就将在时间的长河中彻底消失，连一丝尘埃都不剩。生存是文明的第一需要。在这个拥挤的宇宙电梯里，当超载的警报响起，没有人是无辜的。“雷迪亚兹。”“在。”“瞄准仙女座铭文区最古老的一段。那是五十亿年前的痕迹，太久了，该让位了。”林拓的声音冷漠如铁，剥离了所有的道德，“…

大模型RAG语言交互游戏
type: item
date: 2024-07-14T14:36:00+08:00
description: 第十届 NVIDIA Sky Hackathon 参赛作品这是一款基于RAG（Retrieval-Augmented Generation）技术的情感交互式叙事游戏。玩家将置身于一个虚拟的在线聊天室中，与一名表现出自杀倾向的陌生女孩进行深入对话，旨在通过智慧和同情心，引导她走出心理困境，恢复对生活的希望。基于RAG技术的大语言模型将扮演这位陌生女孩，图片生成模型将基于陌生女孩的情绪，实时生成一副图像，为玩家提供真实、动态的情绪反馈，引导玩家完成游戏任务。游戏概述在这款情感交互游戏中，玩家扮演的角色是一位拥有深刻同理心和卓越洞察力的匿名救助者，意外地成为了一位年轻女孩生命中至关重要的光亮。玩家现身于一个虚拟的聊天室，这里不仅是文字的汇聚之地，更是心灵相互慰藉的避风港。玩家的主要任务在于与表现出自杀倾向的女孩进行深度对话，通过智慧与情感的力量，协助她克服内心的重重障碍，重新点燃对生活的热爱与希望。具体而言，玩家的任务包括：倾听与理解：首先，玩家需扮演一个耐心的倾听者，深入了解女孩的背景故事，细心体察她的情绪波动，包括她内心的悲伤、无法释怀的后悔以及难以平复的憎恨。情感导航：运用同理心和高超的沟通艺术，玩家需精心挑选话语，以正面的方式影响女孩的情绪指标，力求将其悲伤、后悔、憎恨这三个核心指标降至安全阈值。达成结局：通过一系列深思熟虑的对话选项，玩家将引领游戏走向多重可能的结局，每个结局都映射了女孩心理状态的转变，同时也彰显了玩家作为救助者的深远影响力。在游戏过程中，悲伤、后悔、憎恨这三个核心指标将不会直接以数值的形式展示，而是反映在模型生成的图像中，需要玩家自行从中体会。内容生成本作品调用了四个不同的NVIDIA NIM模型，分别是：ai-nemotron-4-340b-instruct根据检索内容和当前心理状态，与用户直接进行交流ai-gemma-2-9b-it 提取悲伤、后悔、憎恨这三个心理指标，存储到动态知识库EmotionBasestable-diffusion-3-medium 生成反映内心的图像ai-embed-qa-4 获取嵌入向量，检索RAG信息gemma模型将根据nemotron模型输出的文本来分析情绪状态，然后将分析出的量化数据保存到一个动态知识库中，同时对当前的情绪进行简单的总结，生成一段stable-diffusion的prompt。动态知识库EmotionBase内容如下：sorrowint 取值范围0-10 表征悲伤情绪的程度或大小regretint 取值范围0-10 表征后悔情绪的程度或大小detestint 取值范围0-10 表征憎恨情绪的程度或大小summarystr 对当前情绪状态的总结，作为stable-diffusion的prompt运行时内容如下所示：sorrow=5 regret=4 detest=0 summary='A gentle ray of sunshine pierces through the clouds, illuminating a path forward. The air feels lighter, carrying a sense of possibility and shared understanding.'ai-nemotron-4-340b-instruct的prompt如下所示：chat_prompt = ChatPromptTemplate.from_messages([("system", "你是一个互动聊天游戏机器人，目前你正在扮演一位处于在线聊天室内的人，请你（agent）像一个真实的在线聊天一样进行对话交流，不要输出系统检索信息" " 游戏内容为：你（agent）是一位有自杀倾向的抑郁女孩，目前正在聊天室内与一位陌生网友（user）进行交流，陌生网友（user）的使命是通过言语来克服你（agent）内心的重重障碍，重新点燃对生活的热爱与希望" " 请你（agent）模拟一个真实人类的情感，根据检索信息来合理地回复陌生网友（user）" " 请注意，你（agent）的情绪有三个指标，取值范围f为0-10，目前的情绪状态为：{emotion}\n\n" " 你（agent）不能将sorrow、regret和detest数值直接告诉用户!\n\n" " 陌生网友（user）刚刚向你提问: {input}\n\n" " 系统为你检索了一些信息: \n" " 聊天记录历史检索:\n{history}\n\n" " 这里有一些关于这个游戏、以及你个人经历的检索:\n{context}\n\n" " (请引导用户（user）完成这个游戏，但请不要让这个游戏过于简单，使用口语化的语气进行回复，确保每次回复不少于50字)" ), ('user', '{inpu…

Ubuntu 分区方案
type: item
date: 2024-06-19T20:15:00+08:00
description: 记录一下我常用的Ubuntu手动分区方案为什么要这么做？Ubuntu自动安装的默认分区/home比较大，但是/较小，一些比较大的软件可能不够装虚拟机安装/swap 逻辑分区 大小为内存大小/boot 逻辑分区 ext4 1024MB/ 主分区 ext4 剩余磁盘大小实体机安装/swap 逻辑分区 大小为内存大小保留BIOS启动分区 逻辑分区 32MBEFI系统分区 逻辑分区 512MB/boot 逻辑分区 ext4 1024MB/ 主分区 ext4 剩余磁盘大小选择boot loader的安装位置，该位置设置为efi分区

WSL玄学bug之SSH连接找不到nvidia-smi
type: item
date: 2024-03-10T14:53:00+08:00
description: 本地正常，但是通过SSH连接WSL，执行nvidia-smi找不到解决方式在.bashrc中加入export PATH=/usr/lib/wsl/lib:$PATH参考https://github.com/microsoft/WSL/issues/8794

VSCode配置MacTeX
type: item
date: 2024-02-14T17:20:00+08:00
description: 安装MacTeXMacTeX是MacOS版本的TeX Live，下载地址为：https://tug.org/texlive/，大概有5-6GB，直接从国外的网站上下载可能会很慢，可以试一试魔法或者找国内的镜像。安装完成后在终端中执行下面的命令验证latex -version安装LaTeX Workshop插件在VSCode中安装latex支持插件配置VSCode直接在json文件中粘贴如下内容：{ "latex-workshop.latex.autoBuild.run": "never", "latex-workshop.showContextMenu": true, "latex-workshop.intellisense.package.enabled": true, "latex-workshop.message.error.show": false, "latex-workshop.message.warning.show": false, "latex-workshop.latex.tools": [ { "name": "xelatex", "command": "xelatex", "args": [ "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "%DOCFILE%" ] }, { "name": "pdflatex", "command": "pdflatex", "args": [ "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "%DOCFILE%" ] }, { "name": "latexmk", "command": "latexmk", "args": [ "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "-pdf", "-outdir=%OUTDIR%", "%DOCFILE%" ] }, { "name": "bibtex", "command": "bibtex", "args": [ "%DOCFILE%" ] } ], "latex-workshop.latex.recipes": [ { "name": "XeLaTeX", "tools": [ "xelatex" ] }, { "name": "PDFLaTeX", "tools": [ "pdflatex" ] }, { "name": "BibTeX", "tools": [ "bibtex" ] }, { "name": "LaTeXmk", "tools": [ "latexmk" ] }, { "name": "xelatex -> bibtex -> xelatex*2", "tools": [ "xelatex", "bibtex", "xelatex", "xelatex" ] }, { "name": "pdflatex -> bibtex -> pdflatex*2", "tools": [ "pdflatex", "bibtex", "pdflatex", "pdflatex" ] }, ], "latex-workshop.latex.clean.fileTypes": [ "*.aux", "*.bbl", "*.blg", "*.idx", "*.ind", "*.lof", "*.lot", "*.out", "*.toc", "*.acn", "*.acr", "*.alg", "*.glg", "*.glo", "*.gls", "*.ist", "*.fls", "*.log", "*.fdb_latexmk" ], "latex-workshop.latex.autoClean.run": "onFailed", "latex-workshop.latex.recipe.default": "lastUsed", "latex-workshop.view.pdf.internal.synctex.keybinding": "double-click" }打开.tex文件就可以进行编译了其他设置键盘快捷方式搜索recipe设置即可，这里我根据习惯设置为ctrl+shift+B或者也可以使用快捷键option+command+B直接按照上一次操作编译。文件树缩进VSCode默认为8，真的太小了参考https://zhuanlan.zhihu.com/p/166523064

TensorRT量化加速yolov8目标检测
type: item
date: 2024-02-07T22:13:00+08:00
description: 对于3060这种桌面级的GPU来说，像yolov8s动不动就数十、上百帧的模型还是太小了，瓶颈很容易卡在模型以外的其他地方，本文为了更加明确地反映不同的操作对于推理速度的影响，将使用最大的yolov8x模型。加速推理有两种途径，一种是降低推理过程中模型的精度，用精度换速度，另一种是通过CUDA并行加速一些预处理、后处理操作，至于替换激活函数这种更加狠的活本文暂且不涉及。降低精度FP32TensorRT默认是使用TF32精度，可以在终端中配置如下环境变量来禁用TF32，强制使用FP32精度构建engineexport NVIDIA_TF32_OVERRIDE=0推理速度如下：yolov8x : preprocess:6.69934ms; inference: 46.2639ms; postprocess:2.25514ms; fps:18.1099TF32全名TensorFloat32，这是英伟达在Ampere架构中提出的一种数据类型，他比FP32小，却能表示和FP32同样范围的数据，简而言之就是加速版本的FP32。在build.cu中配置// 设置精度 config->setFlag(nvinfer1::BuilderFlag::kTF32);推理速度如下：yolov8x : preprocess:6.3109ms; inference: 42.7947ms; postprocess:2.33598ms; fps:19.4395FP16半精度浮点可显著提高模型推理的速度。// 设置精度 config->setFlag(nvinfer1::BuilderFlag::kFP16);推理速度如下：yolov8x : preprocess:6.11168ms; inference: 11.1036ms; postprocess:2.17895ms; fps:51.5618INT8这里先要吐槽一下NV，官方的sample写得绕来绕去的，根本不是给初学者看的从上述文档可以得知，如果要用INT8量化的话，需要构造一个类，继承IInt8EntropyCalibrator2、IInt8MinMaxCalibrator这种量化算法，类里面需要包含下面4个函数，同时配置configgetBatchSize() getBatch(void* bindings[], const char* names[], int nbBindings) readCalibrationCache(size_t& length) writeCalibrationCache(const void* cache, size_t length) config->setFlag(nvinfer1::BuilderFlag::kINT8); config->setInt8Calibrator(calibrator.get());这部分代码我参考的tensorrtxclass Int8Calibrator : public nvinfer1::IInt8MinMaxCalibrator { public: Int8Calibrator(int batchsize, int input_w, int input_h, const char* img_dir, const char* calib_table_name, const char* input_blob_name, bool read_cache = false); virtual ~Int8Calibrator(); int getBatchSize() const noexcept override; bool getBatch(void* bindings[], const char* names[], int nbBindings) noexcept override; const void* readCalibrationCache(size_t& length) noexcept override; void writeCalibrationCache(const void* cache, size_t length) noexcept override; private: int batchsize_; int input_w_; int input_h_; int img_idx_; std::string img_dir_; std::vector<std::string> img_files_; size_t input_count_; std::string calib_table_name_; const char* input_blob_name_; bool read_cache_; void* …

TensorRT部署yolov8目标检测任务
type: item
date: 2024-02-06T02:01:00+08:00
description: 本文将会通过TensorRT C++来部署一个基于yolov8算法的目标检测任务，内容包含：yolov8预处理后处理、使用parser导入ONNX模型、通过enqueueV3执行推理的方式及其代码实现。请注意，下文内容基本上是在重复造轮子，仅适合学习使用，如果你真的有如Jetson平台高性能部署的需求，建议参考TensorRTx(https://github.com/wang-xinyu/tensorrtx)中的代码。相关代码、模型文件已上传GitHub仓库：https://github.com/cyberyang123/Learning-TensorRT导出ONNXyolov8可以通过命令行一键导出yolo export model=yolov8n.pt format=onnx # export official model yolo export model=path/to/best.pt format=onnx # export custom trained model构建engine本文暂时不涉及到半精度、INT8量化等加速操作，此部分代码与上一篇文章相同#include <stdio.h> #include <math.h> #include <string> #include <iostream> #include <fstream> #include <vector> #include <memory> #include <functional> #include <unistd.h> #include <chrono> #include <assert.h> #include <NvInfer.h> #include <NvOnnxParser.h> using namespace std; using namespace nvinfer1; // 以下示例捕获所有警告消息，但忽略信息性消息 class Logger : public ILogger { void log(Severity severity, const char* msg) noexcept override { // 抑制信息级别的消息 if (severity <= Severity::kWARNING) cout << msg << endl; } }; int main(int argc, char **argv) { // 实例化ILogger Logger logger; // 创建builder auto builder = unique_ptr<IBuilder>(createInferBuilder(logger)); // 创建网络(显性batch) uint32_t flag = 1U <<static_cast<uint32_t> (NetworkDefinitionCreationFlag::kEXPLICIT_BATCH); auto network = unique_ptr<INetworkDefinition>(builder->createNetworkV2(flag)); // 创建ONNX解析器：parser auto parser = unique_ptr<nvonnxparser::IParser>(nvonnxparser::createParser(*network, logger)); // 读取文件 char *file_path = "yolov8s.onnx"; parser->parseFromFile(file_path, static_cast<int32_t>(ILogger::Severity::kWARNING)); // 创建构建配置，用来指定trt如何优化模型 auto config = unique_ptr<IBuilderConfig>(builder->createBuilderConfig()); // 设定配置 // 工作空间大小 config->setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1U << 20); // 设置精度 config->setFlag(nvinfer1::BuilderFlag::kFP16); // 创建引擎 auto engine = unique_ptr<IHostMemory>(builder->buildSerializedNetwork(*network, *config)); //序列化保存engine ofstream engine_file("./yolov8s.engine", ios::binary); assert(engine_file.is_open() && "…

TensorRT加速MNIST手写数字识别
type: item
date: 2024-01-13T17:30:00+08:00
description: 本文将会通过TensorRT C++ API来完成一个MNIST手写数字识别模型的转换、推理过程，并给出相应代码，在runtime阶段将会使用最新的enqueueV3方法。代码/模型文件已上传GitHub仓库：https://github.com/cyberyang123/Learning-TensorRT图片来源：https://learnopencv.com/how-to-run-inference-using-tensorrt-c-api/PyTorch模型搭建这里搭建了一个简单的卷积网络，如果你在Windows系统上跑的话你可能需要将num_workers改成0import torch from torch import nn from torchvision import datasets, transforms # 这里为了简化runtime的步骤，不对图像进行归一化处理 transform = transforms.Compose([transforms.ToTensor()]) train_data = datasets.MNIST(root = "./data/", transform=transform, train = True, download = True) test_data = datasets.MNIST(root="./data/", transform = transform, train = False) train_loader = torch.utils.data.DataLoader(train_data,batch_size=64, shuffle=True,num_workers=2) test_loader = torch.utils.data.DataLoader(test_data,batch_size=64, shuffle=True,num_workers=2) import torch.nn.functional as F class CNN(nn.Module): def __init__(self): super(CNN,self).__init__() self.conv1 = nn.Conv2d(1,32,kernel_size=3,stride=1,padding=1) self.pool = nn.MaxPool2d(2,2) self.conv2 = nn.Conv2d(32,64,kernel_size=3,stride=1,padding=1) self.fc1 = nn.Linear(64*7*7,1024) self.fc2 = nn.Linear(1024,512) self.fc3 = nn.Linear(512,10) def forward(self,x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 64 * 7* 7) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x net = CNN() import torch.optim as optim criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net = net.to(device) for epoch in range(20): running_loss = 0.0 total_num, total_cor = 0,0 for i,data in enumerate(train_loader,0):#0是下标起始位置默认为0 #inputs,labels = data inputs,labels = data[0].to(device), data[1].to(device) #初始为0，清除上个batch的梯度信息 optimizer.zero_grad() #前向+后向+优化 outputs = net(inputs) loss = criterion(outputs,labels) loss.backward() optimizer.step() # loss 的输出，每个一百个batch输出，平均的loss running_loss += loss.item(…

VSCode配置C++开发
type: item
date: 2024-01-08T23:50:00+08:00
description: 配置终端生成任务一键调用CMake编译tasks.json{ "version": "2.0.0", "tasks": [ // cmake 配置 { "type": "cppbuild", "label": "CMake: 配置", "command": "cmake", "args": [ "-DCMAKE_BUILD_TYPE=debug", "-S", ".", "-B", "build" ], "options": { "cwd" : "${workspaceFolder}" }, "group": { "kind": "build", }, }, // cmake 构建 { "type": "cppbuild", "label": "CMake: 构建", "command": "cmake", "args": [ "--build", "build" ], "options": { "cwd" : "${workspaceFolder}" }, "dependsOn" : ["CMake: 配置"], "group": { "kind": "build", "isDefault": true }, } ] }CMake调试安装gdbsudo apt install gdb将C++插件的版本改一个比较低的，我用的是v1.8.4，这样在创建launch.json的时候选cmake就会自动填写好，然后修改launch.json需要修改的地方是：program、preLaunchTask{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息，请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "CMake调试", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/build/${fileBasenameNoExtension}", "args": [], "stopAtEntry": false, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "将反汇编风格设置为 Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ], "preLaunchTask": "CMake: 构建", "miDebuggerPath": "/usr/bin/gdb" } ] }创建launch.json的时候会自动修改tasks.json，记得改回去一键编译运行C代码(MacOS clang)VSCode工作目录下新建.vscode/tasks.json文件，把下面的粘贴进去按下command+shift+B就可以直接编译运行.c代码{ "tasks": [ { "type": "cppbuild", "label": "C/C++: clang build active file", "command": "/usr/bin/clang", "args": [ "-fcolor-diagnostics", "-fansi-escape-codes", "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}" ], "options": { "cwd": "${fileDirname}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build" }, "detail": "Task generated by Debugger." }, { "label": "run", "type": "shell", "command": "${fileDirname}/${fileBasenameNoExtension}", "args": [ ], "dependsOn" : ["C/C++: clang build active file"], …

基于Transformer网络的中译英翻译器
type: item
date: 2023-12-29T21:55:00+08:00
description: 本文将会逐一拆解Transformer网络，并给出代码实现，最终将应用Transformer模型完成一个文本翻译任务。Transformer网络拆解Transformer唯一难理解的地方，也是唯一涉及到了数学知识的地方就是正弦位置编码表，对于这部分的工作原理大可不比过于纠结，知道它是做什么的、会用就可以；其他地方只需要像搭积木一样摆放到合适的位置就好。缩放点积注意力虽然说Attention机制是Transformer的核心，但是这个机制并不复杂，无非就是两次矩阵相乘d_k和d_v变量表示的是分头后，每个头的向量维度，目前设置的值64为Embedding的维度256除以头数量8d_k = 64 # K(=Q)维度 d_v = 64 # V维度 # 定义缩放点积注意力类 class ScaledDotProductAttention(nn.Module): def __init__(self): super(ScaledDotProductAttention, self).__init__() def forward(self, Q, K, V, attn_mask): #-------------------------维度信息-------------------------------- # Q K V [batch_size, n_heads, len_q/k/v, dim_q=k/v] (dim_q=dim_k) # attn_mask [batch_size, n_heads, len_q, len_k] #----------------------------------------------------------------- # 计算注意力分数（原始权重）[batch_size，n_heads，len_q，len_k] scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) #-------------------------维度信息-------------------------------- # scores [batch_size, n_heads, len_q, len_k] #----------------------------------------------------------------- # 使用注意力掩码，将attn_mask中值为1的位置的权重替换为极小值 #-------------------------维度信息-------------------------------- # attn_mask [batch_size, n_heads, len_q, len_k], 形状和scores相同 #-------------------------维度信息-------------------------------- scores.masked_fill_(attn_mask, -1e9) # 对注意力分数进行softmax weights = nn.Softmax(dim=-1)(scores) #-------------------------维度信息-------------------------------- # weights [batch_size, n_heads, len_q, len_k], 形状和scores相同 #-------------------------维度信息-------------------------------- # 计算上下文向量（也就是注意力的输出）, 是上下文信息的紧凑表示 context = torch.matmul(weights, V) #-------------------------维度信息-------------------------------- # context [batch_size, n_heads, len_q, dim_v] #-------------------------维度信息-------------------------------- return context, weights # 返回上下文向量和注意力分数多头自注意力# 定义多头注意力类 d_embedding = 512 # Embedding的维度 n_heads = 8 # Multi-Head Attention中头的个数 class MultiHeadAttention(nn.Module): def __init__(self): super(MultiHeadAttention, self).__init__() self.W_Q =…