LLM笔记(二)LLM数据基础
核心目标: 构建 LLM 的数据基础,将原始文本转化为模型可处理的、包含丰富语义和结构信息的数值形式。
一、 环境与库准备 (Environment & Libraries):
- 必要库确认: 在开始之前,确保
torch
(PyTorch深度学习框架) 和tiktoken
(OpenAI的高效BPE分词器库) 已正确安装。可以通过以下代码检查它们的版本,这是后续代码能顺利运行的前提。from importlib.metadata import version import torch # 确保导入torch,虽然版本检查在下面,但先导入无妨 import tiktoken # 确保导入tiktokenprint("torch version:", version("torch")) print("tiktoken version:", version("tiktoken")) # 确认库已安装并显示当前安装的版本
- 本书代码仓库:
- 英文原版:
https://github.com/rasbt/LLMs-from-scratch
- 汉化版 (供参考):
https://github.com/GoatCsu/CN-LLMs-from-scratch.git
- 英文原版:
二、 理解文字嵌入 (Understanding Word Embeddings) (2.1):
基础概念
- 核心概念: 将离散的文本单元(如词语、子词)转换为计算机能够理解和处理的稠密数值向量(嵌入向量)。这些向量在高维空间中捕捉词语的语义关系。
- 高维视角: LLM 通常在非常高(例如上千)维度的空间中理解和表示文本,这远超人类的直观想象能力。
- 二维模拟 (辅助理解): 我们可以通过二维或三维的降维可视化来粗略地理解嵌入空间的概念,例如语义相似的词语在空间中会聚集在一起。
- 本书重点: 本章及后续内容将主要关注文本嵌入中的词嵌入 (word embeddings) 和 子词嵌入 (subword embeddings),因为这是构建类GPT模型的基础。
三、 文本分词/令牌化 (Tokenizing Text) (2.2):
-
目标: 将连续的文本字符串拆解成一系列离散的、模型易于处理的基本单元,这些单元被称为令牌 (tokens)。令牌可以是完整的词、有意义的子词(如词根、词缀),甚至是单个字符或字节。
图示:词元化 (Tokenization) 是将原始文本数据转换为LLM能够处理的离散单元的第一步。 -
实践步骤:
- 载入源数据: 首先,我们需要一个文本源作为处理对象。本章以 Edith Wharton 的短篇小说 “The Verdict” (已进入公共领域) 为例。
import os import urllib.requestfile_name = "the-verdict.txt" if not os.path.exists(file_name):url = ("https://raw.githubusercontent.com/rasbt/""LLMs-from-scratch/main/ch02/01_main-chapter-code/""the-verdict.txt")urllib.request.urlretrieve(url, file_name)print(f"Downloaded '{file_name}'") else:print(f"'{file_name}' already exists.")with open(file_name, "r", encoding="utf-8") as f:raw_text = f.read() ##读入文件按照utf-8print(f"\nTotal number of characters in '{file_name}': {len(raw_text)}") print(f"First 99 characters:\n{raw_text[:99]}")
- 使用正则表达式进行初步分词:
- 正则表达式是一种强大的文本匹配工具,可以用来根据预定义的模式(如标点符号、空白字符)来分割文本。
图示:展示了使用正则表达式将文本分割成令牌的过程。
import re# 示例简单文本 example_text_regex = "Hello, world. Is this-- a test?"# 初始分割(仅按空白) # result_initial = re.split(r'(\s)', example_text_regex) # print(f"Initial split: {result_initial}")# 优化分割(按逗号、句号和空白) # result_punct = re.split(r'([,.]|\s)', example_text_regex) # print(f"Split with some punctuation: {result_punct}")# 去除空白项 # result_no_space_items = [item for item in result_punct if item.strip()] # print(f"Split with punctuation, no empty/space items: {result_no_space_items}")# 更全面的正则表达式,处理更多标点符号 comprehensive_regex = r'([,.:;?_!"()\']|--|\s)' preprocessed_tokens_list = re.split(comprehensive_regex, raw_text) ##按照符号继续把原文件给分割了 # 去掉两端的空白字符,同时移除因分割产生的空字符串和仅包含空白字符的项 preprocessed_tokens_list = [item.strip() for item in preprocessed_tokens_list if item.strip()]print(f"\nFirst 30 preprocessed tokens from 'the-verdict.txt':\n{preprocessed_tokens_list[:30]}") print(f"Total number of preprocessed tokens: {len(preprocessed_tokens_list)}") # 示例输出约4690
- 正则表达式是一种强大的文本匹配工具,可以用来根据预定义的模式(如标点符号、空白字符)来分割文本。
- 载入源数据: 首先,我们需要一个文本源作为处理对象。本章以 Edith Wharton 的短篇小说 “The Verdict” (已进入公共领域) 为例。
四、 将令牌转换为令牌ID (Converting Tokens into Token IDs) (2.3):
-
目标: 为词汇表中的每一个唯一的令牌分配一个独一无二的整数ID。这是将文本进一步数值化的关键步骤。
图示:将分词后的文本令牌映射为整数ID的过程。 -
步骤与代码:
-
创建词汇表 (Vocabulary):
# 从预处理后的令牌列表中提取所有唯一的令牌,并排序 all_unique_words = sorted(list(set(preprocessed_tokens_list))) vocab_size_simple = len(all_unique_words) print(f"Vocabulary size (SimpleTokenizer): {vocab_size_simple}") # 示例输出1130# 使用字典推导式生成词汇表,key是token字符串,value是整数ID # enumerate(all_unique_words) 会生成 (索引, 令牌) 的元组 vocab_simple = {token: integer for integer, token in enumerate(all_unique_words)}
-
查看词汇表示例:
print("\nFirst 50 entries in the simple vocabulary:") for i, (token_str, token_id) in enumerate(vocab_simple.items()):print(f"'{token_str}': {token_id}")if i >= 49: # 打印50个break
图示:展示了词汇表的一部分,将词语或标点符号映射到整数。 -
实现简单的分词器类 (
SimpleTokenizerV1
):class SimpleTokenizerV1:def __init__(self, vocab_dict): # 接收词汇表字典作为参数self.str_to_int = vocab_dictself.int_to_str = {i: s for s, i in vocab_dict.items()} # 创建反向映射def encode(self, text_input: str) -> list[int]:# 使用与构建词汇表时相同的正则表达式和处理方式preprocessed = re.split(r'([,.:;?_!"()\']|--|\s)', text_input)preprocessed = [item.strip() for item in preprocessed if item.strip()]# 注意:这里假设所有 preprocessed 中的 item 都能在 self.str_to_int 中找到# 如果词汇表不完整,这里会抛出 KeyErrorids = [self.str_to_int[s] for s in preprocessed]return idsdef decode(self, ids_input: list[int]) -> str:text_tokens = [self.int_to_str[i] for i in ids_input]text = " ".join(text_tokens)# 替换标点符号前的多余空格text = re.sub(r'\s+([,.:;?!"()\'])', r'\1', text)return text
图示:SimpleTokenizerV1类的encode和decode过程。
-
五、 添加特殊上下文令牌 (Adding Special Context Tokens) (2.4):
-
目的: 使用特殊标记来帮助LLM处理如文本边界、未知词等特殊情况,从而获取更丰富的上下文信息。
-
常用的通用特殊标记:
[BOS]
(序列开始)[EOS]
(序列结束)[PAD]
(填充)[UNK]
(未知词)
-
GPT-2分词器的特殊性:
- 主要使用
<|endoftext|>
作为结束和填充标记。 - 通过BPE处理未知词,不依赖
<UNK>
。 - 在独立文本之间使用
<|endoftext|>
进行分隔。
- 主要使用
-
SimpleTokenizer
类 (V2, 处理<|unk|>
)# 重新构建词汇表,加入特殊token all_tokens_list_extended = sorted(list(set(preprocessed_tokens_list))) all_tokens_list_extended.extend(["<|endoftext|>", "<|unk|>"]) # 添加特殊token vocab_extended = {token: integer for integer, token in enumerate(all_tokens_list_extended)}class SimpleTokenizerV2: # 与您提供的代码一致def __init__(self, vocab_param): # 明确参数名self.str_to_int = vocab_paramself.int_to_str = {i: s for s, i in vocab_param.items()}def encode(self, text_param: str) -> list[int]:preprocessed = re.split(r'([,.:;?_!"()\']|--|\s)', text_param)preprocessed = [item.strip() for item in preprocessed if item.strip()]processed_tokens = []for item in preprocessed:if item in self.str_to_int:processed_tokens.append(item)else:processed_tokens.append("<|unk|>") # 确保 <|unk|> 在词汇表中ids = [self.str_to_int[s] for s in processed_tokens]return idsdef decode(self, ids_param: list[int]) -> str:text_tokens = [self.int_to_str[i] for i in ids_param]text = " ".join(text_tokens)text = re.sub(r'\s+([,.:;?!"()\'])', r'\1', text)return text# 使用示例 tokenizer_v2_instance = SimpleTokenizerV2(vocab_extended) text1_example = "Hello, do you like tea?" text2_example = "In the sunlit terraces of the palace." combined_text_example = " <|endoftext|> ".join((text1_example, text2_example)) print(f"\nCombined text with special token:\n{combined_text_example}") encoded_ids_v2 = tokenizer_v2_instance.encode(combined_text_example) print(f"Encoded IDs (V2): {encoded_ids_v2}") decoded_text_v2 = tokenizer_v2_instance.decode(encoded_ids_v2) print(f"Decoded text (V2): {decoded_text_v2}")
- 关键点强调:
- 初始化时传入的
vocab_extended
必须包含<|unk|>
和<|endoftext|>
。 encode
方法现在会将词汇表中不存在的词映射为<|unk|>
对应的ID。
- 初始化时传入的
- 关键点强调:
六、 字节对编码 (Byte Pair Encoding, BPE) (2.5):
- 背景: 为了更有效地处理未知词和控制词汇表大小,GPT-2等模型采用BPE分词。BPE能够将词语分解为有意义的子词单元,从而大幅减少OOV情况,并能表示新词和罕见词。
图示:BPE通过合并高频字节对来构建词汇表和切分词语。 tiktoken
库: OpenAI 提供的官方BPE实现,性能较高。- 实践代码:
import tiktoken# 获取GPT-2的BPE分词器 bpe_tokenizer = tiktoken.get_encoding("gpt2")text_for_bpe = ("Hello, do you like tea? <|endoftext|> In the sunlit terraces"" of someunknownPlace." ) # 使用BPE进行编码,允许<|endoftext|>作为特殊标记 bpe_encoded_ids = bpe_tokenizer.encode(text_for_bpe, allowed_special={"<|endoftext|>"}) print(f"\nBPE Encoded IDs: {bpe_encoded_ids}")# 使用BPE进行解码 bpe_decoded_text = bpe_tokenizer.decode(bpe_encoded_ids) print(f"BPE Decoded text: {bpe_decoded_text}")
- BPE的优势: BPE能够将未知词(如 “someunknownPlace”)分解为已知的子词序列,而不是简单地替换为
<UNK>
,从而保留了更多的语义信息。
- BPE的优势: BPE能够将未知词(如 “someunknownPlace”)分解为已知的子词序列,而不是简单地替换为
七、 使用滑动窗口进行数据采样 (Data Sampling with a Sliding Window) (2.6):
- 目标: 为LLM的“下一词预测”训练任务准备输入-目标对。模型根据一段输入文本(上下文)来预测序列中的下一个词。
图示:滑动窗口方法将长文本切分为多个输入-目标对。 GPTDatasetV1
类 :__init__
:接收完整文本、分词器、最大序列长度 (max_length
) 和步幅 (stride
)。将整个文本编码为token ID,然后使用滑动窗口切分出input_chunk
和target_chunk
(目标块是输入块向右平移一位)。__len__
:返回数据集中样本(即切分出的块)的数量。__getitem__
:根据索引返回一个输入块和目标块。
create_dataloader_v1
函数 (已在您提供的代码中):- 封装了
GPTDatasetV1
的实例化和torch.utils.data.DataLoader
的创建。DataLoader
负责批处理、数据打乱等。
- 封装了
- 代码示例 (演示DataLoader工作方式):
# 假设 raw_text 已经加载 # dataloader = create_dataloader_v1( # raw_text, batch_size=8, max_length=4, stride=4, shuffle=False # ) # data_iter = iter(dataloader) # inputs_batch, targets_batch = next(data_iter) # print("Inputs Batch:\n", inputs_batch) # print("\nTargets Batch:\n", targets_batch)
八、 创建令牌嵌入 (Creating Token Embeddings) (2.7):
- 目标: 将离散的整数令牌ID转换为稠密的、连续的向量表示(嵌入向量)。这是LLM能够处理数值输入的基础。
图示:将Token ID通过嵌入层映射为嵌入向量。 torch.nn.Embedding
层: PyTorch中实现嵌入层的主要模块。- 本质是查找表: 接收一个token ID作为输入,输出该ID对应的嵌入向量。
- 权重矩阵:
embedding_layer.weight
是一个形状为(vocab_size, output_dim)
的可学习参数矩阵,存储了每个token的嵌入向量。
- 代码示例:
import torch # 确保导入input_ids_example = torch.tensor([2, 3, 5, 1]) # 示例token IDs vocab_size_example = 6 # 词汇表大小(嵌入层支持的唯一标记总数) output_dim_example = 3 # 嵌入向量的维度torch.manual_seed(123) # 设置随机种子以保证结果可复现 embedding_layer_example = torch.nn.Embedding(vocab_size_example, output_dim_example) # 每行表示一个标记的嵌入向量print("\nEmbedding Layer Weight Matrix:") print(embedding_layer_example.weight) print("\nEmbedding for token ID 3:") print(embedding_layer_example(torch.tensor([3]))) # 第4行 (索引从0开始) print("\nEmbeddings for input_ids_example:") print(embedding_layer_example(input_ids_example))
图示:嵌入层权重矩阵和查找过程。
九、 编码词语位置 (Encoding Word Positions) (2.8):
- 问题: 单纯的词嵌入无法区分同一个词在句子中不同位置的含义。
- 解决方案 (GPT-2使用绝对位置嵌入): 引入位置嵌入,与词嵌入相加,使模型能够感知词语的顺序和相对位置。
- 实现步骤:
- 词嵌入层: (同上)
vocab_size_gpt = 50257 embedding_dim_gpt = 256 # GPT-2 small的嵌入维度 token_embedding_layer_gpt = torch.nn.Embedding(vocab_size_gpt, embedding_dim_gpt)
- 位置嵌入层: 创建另一个
nn.Embedding
层,其“词汇表大小”为最大上下文长度 (context_length
),嵌入维度与词嵌入相同。# 假设处理的序列最大长度 (也是位置嵌入要覆盖的范围) max_seq_length = 4 # 示例长度 context_length_for_pos = max_seq_length pos_embedding_layer_gpt = torch.nn.Embedding(context_length_for_pos, embedding_dim_gpt)# 为当前序列生成位置IDs (0, 1, 2, ...) position_ids_gpt = torch.arange(max_seq_length) position_embeddings_gpt = pos_embedding_layer_gpt(position_ids_gpt) # position_embeddings_gpt.shape 将是 torch.Size([max_seq_length, embedding_dim_gpt])
- 合并词嵌入与位置嵌入: 将词嵌入和位置嵌入按元素相加。
# 假设我们有一个批次的token IDs # batch_input_ids = torch.randint(0, vocab_size_gpt, (2, max_seq_length)) # 示例批次 (batch_size=2, seq_len=4) # token_embeddings_batch = token_embedding_layer_gpt(batch_input_ids) # token_embeddings_batch.shape 将是 torch.Size([2, max_seq_length, embedding_dim_gpt])# 为了演示,我们使用之前笔记中的 mock_token_embeddings batch_size_final = 2 sequence_length_final = max_seq_length torch.manual_seed(123) mock_token_embeddings_final = torch.randn(batch_size_final, sequence_length_final, embedding_dim_gpt)# 位置嵌入需要广播到批次中的每个样本 # position_embeddings_gpt 的形状是 [sequence_length, embedding_dim] # mock_token_embeddings_final 的形状是 [batch_size, sequence_length, embedding_dim] # PyTorch 会自动进行广播 final_input_embeddings_gpt = mock_token_embeddings_final + position_embeddings_gpt print(f"\nShape of final input embeddings: {final_input_embeddings_gpt.shape}") # 输出: Shape of final input embeddings: torch.Size([2, 4, 256])
- 词嵌入层: (同上)
**
- 整体输入处理流程回顾图示:**
- 输入文本 (Input text): 原始的文本字符串
- 分词 (Tokenized text): 文本被分词器(如BPE)分割成独立的标记序列
- 标记ID (Token IDs): 每个标记根据预定义的词汇表转换为其对应的整数ID,例如 ``。
- 词嵌入 (Token embeddings): 每个token ID通过词嵌入层转换为一个高维向量(例如256维)。
- 位置嵌入 (Positional embeddings): 为序列中的每个位置生成一个对应的位置嵌入向量。
- 最终输入嵌入 (Input embeddings to LLM): 将词嵌入和位置嵌入相加,得到最终输入给LLM后续层(如Transformer块)的表示。
相关文章:
LLM笔记(二)LLM数据基础
核心目标: 构建 LLM 的数据基础,将原始文本转化为模型可处理的、包含丰富语义和结构信息的数值形式。 一、 环境与库准备 (Environment & Libraries): 必要库确认: 在开始之前,确保 torch (PyTorch深度学习框架) 和 tiktoken (OpenAI的高效BPE分词…...
让三个线程(t1、t2、t3)按顺序依次打印 A、B、C
public class ThreadWait {private static final Object lock = new Object();private static boolean t1Output=true;private static boolean t2Output=false;private static boolean t3Output=false;public static void main(String[] args) {//线程1new Thread(new Runnable…...
2、ubantu系统配置OpenSSH | 使用vscode或pycharm远程连接
1、OpenSSH介绍 OpenSSH(Open Secure Shell)是一套基于SSH协议的开源工具,用于在计算机网络中提供安全的加密通信。它被广泛用于远程系统管理、文件传输和网络服务的安全隧道搭建,是保护网络通信免受窃听和攻击的重要工具。 1.1…...
idea启动报错:java: 警告: 源发行版 11 需要目标发行版 11(亲测解决)
引起原因 idea的jdk没有替换干净 1.配置project file–Project Structrue–Project 2.配置Modules-Sources file–Project Structrue–Modules-Sources 改为jdk11 3.配置Modules-Dependencies file–Project Structrue–Modules-Dependencies...
Pycharm IDEA加载大文件时报错:The file size exceeds configured limit
解决方案:配置一下idea.properties文件 文件里面写入代码: idea.max.intellisense.filesize50000重启IDEA即可;...
视频分辨率增强与自动补帧
一、视频分辨率增强 1.传统分辨率增强方法 传统的视频分辨率增强方法主要基于插值技术。这些方法通过对低分辨率视频帧中已知像素点的分布规律和相邻像素之间的相关性进行分析,在两者之间插入新的像素点以达到增加视频分辨率的目的。例如,最近邻插值算…...
深度学习让鱼与熊掌兼得
通常,一个大的复杂的模型的loss会低,但是拟合方面不够,小的模型在拟合方面更好,但是loss高,我们可以通过深度学习来得到一个有着低loss的小模型 我们之前学过,peacewise linear可以用常数加上一堆这个阶梯型函数得到,然后因为peacewise linear可以逼近任何function,所以理论上…...
面试 Linux 运维相关问题
标题Q1Shell脚本是什么、它是必需的吗? Shell脚本是一种用于自动化执行命令行任务的脚本程序,通常运行在Unix/Linux系统的Shell环境中(如Bash)。它通过将多个命令、逻辑控制(如条件判断、循环)和系统功能整合到一个文…...
阿里巴巴 1688 数据接口开发指南:构建自动化商品详情采集系统
在电商行业数据驱动决策的趋势下,高效获取商品详情数据成为企业洞察市场、优化运营的关键。通过阿里巴巴 1688 数据接口构建自动化商品详情采集系统,能够快速、精准地采集海量商品信息。本文将从开发准备、接口分析、代码实现等方面,详细介绍…...
python的宫崎骏动漫电影网站管理系统
目录 技术栈介绍具体实现截图系统设计研究方法:设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理,难度适中…...
答题pk小程序道具卡的获取与应用
道具卡是答题PK小程序中必不可少的一项增加趣味性的辅助应用,那么道具卡是如何获取与应用的呢,接下来我们来揭晓答案: 一、道具卡的获取: 签到获取:在每日签到中签到不仅可获得当日的签到奖励积分,同时连…...
从零开始创建一个 Next.js 项目并实现一个 TodoList 示例
Next.js 是一个基于 React 的服务端渲染框架,它提供了很多开箱即用的功能,如自动路由、API 路由、静态生成、增量静态再生等。本文将带你一步步创建一个 Next.js 项目,并实现一个简单的 TodoList 功能。 效果地址 🧱 安装 Next.j…...
全面掌握JSR303校验:从入门到实战
一、JSR303校验简介 JSR303是Java EE 6中的一项规范,全称为"Bean Validation 1.0",它定义了一套基于注解的JavaBean校验机制。通过简单的注解,我们可以优雅地完成参数校验工作,避免在业务代码中编写大量的校验逻辑。 …...
「Java EE开发指南」如何使用MyEclipse的可视化JSF编辑器设计JSP?(二)
Visual JSF Designer(可视化JSF设计器)的目标是使创建JSF应用程序的特定于组件工作更容易可视化,在本教程中,您将使用可视化设计器设计JSF登录页面。您将学习如何: 创建一个JSF项目创建一个新的JSF页面设计JSF页面 该…...
Python 翻译词典小程序
一、概述 本工具是基于Python开发的智能翻译系统,采用有道词典进行翻译,并具有本地词典缓存以及单词本功能。 版本号:v1.0 (2025-05-15) 二、核心功能说明 1. 基础翻译功能 即时翻译:输入英文单词自动获取中文释义 词性识别&…...
kafka调优
以下是 Kafka 性能调优的核心策略与参数配置建议,综合生产环境和硬件层面的优化方案,覆盖生产者、消费者、Broker 三个关键组件: 一、生产者调优 批量发送优化 • batch.size:增大批量消息大小(默认 16KB,建…...
【hadoop】sqoop案例 hive->mysql
将temperature.log中的气象数据导入到Hive的temperature表中, 根据气象站id分组计算每个气象站30年来的*最高*气温, 然后将统计结果导出到MySQL当中。 思路: 1.在hive中创建表 2.数据导入到表中 3.计算后的结果写入另外的表 4.用sqoop导出…...
Git/GitLab日常使用的命令指南来了!
在 GitLab 中拉取并合并代码的常见流程是通过 Git 命令来完成的。以下是一个标准的 Git 工作流,适用于从远程仓库(如 GitLab)拉取代码、切换分支、合并更新等操作。 🌐 一、基础命令:拉取最新代码 # 拉取远程仓库的所…...
遗传算法求解旅行商问题分析
目录 一、问题分析 二、实现步骤 1)初始化种群 2)计算适应度 3)选择操作 4)交叉操作 5)变异操作 三、求解结果 四、总结 本文通过一个经典的旅行商问题,详细阐述在实际问题中如何运用遗传算法来进…...
【Hadoop】伪分布式安装
【Hadoop】伪分布式安装 什么是 Hadoop 伪分布式安装? Hadoop 伪分布式安装(Pseudo-Distributed Mode) 是一种在单台机器上模拟分布式集群环境的部署方式。它是介于 本地模式(Local Mode) 和 完全分布式模式…...
微服务概述
什么是微服务 微服务是一个架构方案,属于分布式架构的一种。 微服务提倡将模块以独立服务的方式独立管理,整个项目依靠多个小型的服务(单独进程)同时运作来支撑,单个服务只关注自己的业务实现并且有专业的团队进行开发。服务之间使用轻量的协议进行消息传送,并且对于单个…...
【网工】华为配置基础篇①
目录 ■华为设备登录配置 ■VLAN与VLANIF地址配置 ■DHCP配置命令 ■ACL访问控制列表配置 ■NAT地址转换配置 ■华为设备登录配置 <AR> system-view //进入系统模式 [AR]sysname Huawei //设备命名为Huawei [Huawei] telnet server enable //开启设备telnet功…...
React19源码系列之 Diff算法
在之前文章中root.render执行的过程,beginWork函数是渲染过程的核心,其针对不同类型的fiber进行不同的更新处理,在FunctionComponent(函数组件)中,会针对新旧fiber进行对比处理生成新fiber。因此此次就详细…...
华为2024年报:鸿蒙生态正在取得历史性突破
华为于2025年03月31日发布2024年年度报告。报告显示,华为经营结果符合预期,实现全球销售收入 8,621 亿元人民币,净利润 626 亿元人民币。2024 年研发投入达到 1,797 亿元人民币,约占全年收入的 20.8%,近十年累计投入的…...
如何在Firefox火狐浏览器里-安装梦精灵AI提示词管理工具
第一步:进入《梦精灵跨平台AI提示词管理工具》官网 梦精灵 跨平台AI提示词管理助手 - 官网梦精灵是一款专为AI用户打造的跨平台提示词管理插件,支持一键收藏、快速复制、智能分类等功能,适用于即梦、豆包、Kimi、DeepSeek等多个AI平台&…...
【鸿蒙开发】性能优化
语言层面的优化 使用明确的数据类型,避免使用模糊的数据类型,例如ESObject。 使用AOT模式 AOT就是提前编译,将字节码提前编译成机器码,这样可以充分优化,从而加快执行速度。 未启用AOT时,一边运行一边进…...
Makefile与CMake
一、Makefile 核心内容 1. Makefile 基础结构与工作原理 三要素: 目标(Target):要生成的文件或执行的操作(如可执行文件、清理操作)。依赖(Dependency):生成目标所需的…...
P8803 [蓝桥杯 2022 国 B] 费用报销
P8803 [蓝桥杯 2022 国 B] 费用报销 - 洛谷 题目描述 小明在出差结束后返回了公司所在的城市,在填写差旅报销申请时,粗心的小明发现自己弄丢了出差过程中的票据。 为了弥补小明的损失,公司同意小明用别的票据进行报销,但是公司财…...
11 web 自动化之 DDT 数据驱动详解
文章目录 一、DDT 数据驱动介绍二、实战 一、DDT 数据驱动介绍 数据驱动: 现在主流的设计模式之一(以数据驱动测试) 结合 unittest 框架如何实现数据驱动? ddt 模块实现 数据驱动的意义: 通过不同的数据对同一脚本实现…...
15:00开始面试,15:06就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到4月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...
深入理解浏览器渲染引擎:底层机制与性能优化实战
现代浏览器背后是一个庞大而复杂的系统工程,渲染引擎作为核心模块之一,承担着从解析 HTML/CSS 到最终绘制页面的关键职责。本文将从底层机制出发,系统梳理渲染引擎(如 Blink)工作原理、V8 与渲染流程的协作方式&#x…...
【LeetCode 热题 100】56. 合并区间 —— 一文弄懂排序+遍历经典解法(附Python代码)
📌 题目链接 LeetCode 56. 合并区间 📖 一、引言:区间合并,刷题路上的绊脚石? 区间类问题是算法面试中常见的经典题型,尤其是“合并区间”问题,考察你对排序、区间重叠判断及边界处理的理解和编码能力。 很多同学在面对这题时,容易卡在: 什么时候两个区间算重叠?…...
使用Mathematica绘制Clifford奇异吸引子
Clifford Attractors 是一种由微分方程 生成的混沌吸引子,参数a,b,c,d不同会产生不同的分形图案。这类吸引子属于迭代函数系统,通过不断迭代参数方程来生成复杂的图形。其数学基础可能与 Clifford 代数或高维函数理论相关,例如 Clifford 代数…...
各个历史版本mysql/tomcat/Redis/Jdk/Apache下载地址
mysql 各版本下载地址: https://downloads.mysql.com/archives/community/ **************************************************************** tomcat 各版本下载地址: https://archive.apache.org/dist/tomcat/ ********************************…...
全面解析机器学习与深度学习中的模型权重文件格式与应用场景
概述 随着机器学习和人工智能技术的飞速发展,高效且安全地存储、共享和部署训练有素的模型的方法变得越来越重要。模型权重文件格式在这个过程中发挥着关键作用。这些格式不仅保存了模型的学习参数,还能够实现可复现性,并且便于在各种不同环…...
鸿蒙OSUniApp 实现的地图定位与导航功能#三方框架 #Uniapp
UniApp 实现的地图定位与导航功能 随着移动互联网的发展,地图定位与导航功能已成为众多应用的标配。本文将详细介绍如何在 UniApp 框架下实现地图定位与导航功能,并探讨如何适配鸿蒙系统,助力开发者打造更加流畅的地图体验。 前言 最近在做一…...
【HarmonyOS 5】鸿蒙星闪NearLink详解
【HarmonyOS 5】鸿蒙星闪NearLink详解 一、前言 鸿蒙星闪NearLink Kit 是 HarmonyOS 提供的短距离通信服务,支持星闪设备间的连接、数据交互。例如,手机可作为中心设备与外围设备(如鼠标、手写笔、智能家电、车钥匙等)通过星闪进…...
Java并发编程面试题总结
目录 线程有哪几种状态?状态如何流转? 创建线程的方式? 多线程有什么应用? 线程池的好处? 线程池的七个参数? 为什么不推荐使用jdk的Executors创建线程池? 线程池的执行流程? 任务拒绝策略有哪些,怎么选择? 线程池的核心线程数和最大线程数怎么设定…...
LAMP项目部署实战
一、LAMP部署前期准备 1.1 关闭防火墙 # systemctl stop firewalld # systemctl disable firewalld 1.2 关闭SELinux SELinux(Security-EnhancedLinux)是美国国家安全局(NSA)对于强制访问控制的实现,是Linux历史上最杰出的新安全子系统。 …...
Dify与n8n全面对比指南:AI应用开发与工作流自动化平台选择【2025最新】
Dify与n8n全面对比指南:AI应用开发与工作流自动化平台选择【2025最新】 随着AI技术与自动化工具的迅速发展,开发者和企业面临着多种平台选择。Dify和n8n作为两个备受关注的自动化平台,分别专注于不同领域:Dify主要面向AI应用开发&…...
VBA_NZ系列工具NZ10:VBA压缩与解压工具
我的教程一共九套及VBA汉英手册一部,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到数据库,到字典,到高级的网抓及类的应用。大家在学习的过程中可能会存在困惑,这么多知识点该如何组织…...
EFT不过整改思路与调试经验
EFT是如何影响EUT的: EFT试验是为了验证电气和电子设备对诸如来自切换瞬态过程(切断感性负载、继电器触点弹跳等)的各种类型瞬变骚扰的抗扰度。EFT干扰是在电路中感性负载断开时产生的,它的特点是干扰信号不是单个脉而是一连串的脉冲群。EFT 干扰可以在…...
2.安卓逆向2-adb指令
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于:图灵Python学院 工具下载: 链接:https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取码࿱…...
VSCode CMake工作流
Foreword 之前看到CMake有这么多选项,感觉不简单,还是看下别人在这里设计了多少东西 CMake 整体来说CMake遵循这样一套结构 操作-操作预设(如果有的话)-操作目标(如果有的话)比如 Configure-Configure…...
【上位机——WPF】App.xml和Application类简介
App.xml和Application类简介 概述App.xamlApp.xaml.cs 入门代码App.xamlMainWindow.xml Application生命周期窗体的声明周期 概述 xaml类型的文件包含两部分,一部分以.xaml扩展名结尾的前端代码,另一部分以.xaml.cs结尾的后端代码,通常我们也…...
MySQL 8.0 OCP 1Z0-908 101-110题
Q101.which two queries are examples of successful SQL injection attacks? A.SELECT id, name FROM backup_before WHERE name‘; DROP TABLE injection; --’; B. SELECT id, name FROM user WHERE id23 oR id32 OR 11; C. SELECT id, name FROM user WHERE user.id (SEL…...
Linux/Centos7离线安装并配置MySQL 5.7
文章目录 前言1、安装包下载2、卸载MariaDB3、创建MySQL用户4、上传安装包5、创建数据目录和配置文件6、安装MySQL7、启动MySQL8、初始化MySQL9、退出验证新密码10、创建普通用户和库11、测试普通用户和库总结 前言 博主参考了一些大佬的文章,部分收费的就看不了了&…...
在Angular中使用Leaflet构建地图应用
Leaflet是一个用于创建地图的JavaScript库,它包含许多功能,并且非常适用于移动设备。 准备 nodejs: v20.15.0 npm: 10.7.0 angular: 19.2.10 创建一个地图应用工程 npx angular/cli new my-leaflet-app --stylecss --routingfalse --skip-tests提示 …...
GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践
点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,按量计费,灵活弹性,顶级配置,学生专属优惠。 引言 在边缘计算与AI推理场景中,GPU-NPU异构计算架构已成为突破算力瓶颈的关键技…...
iOS 抓包实战:从 Charles 到Sniffmaster 的日常工具对比与使用经验
iOS 抓包实战:从 Charles 到抓包大师 Sniffmaster 的日常工具对比与使用经验 抓包这件事,不是高级黑客才要做的。作为一名移动端开发,我几乎每天都要和网络请求打交道,尤其是 HTTPS 请求——加密、重定向、校验证书,各…...