当前位置: 首页 > article >正文

EMDB:面向MCU的嵌入式键值数据库设计与实践

1. 项目概述EMDBEmbedded Micro Database是一个专为资源受限嵌入式系统设计的极简型键值数据库其核心目标是在微控制器级别提供可查询、可持久化、内存友好的数据管理能力。与传统嵌入式KV存储如简单的哈希表或链表缓存不同EMDB在设计之初即内建查询语义支持并预留了面向闪存/SD卡等非易失介质的存储后端扩展路径。它并非SQLite的轻量裁剪版而是一套从底层数据结构、内存布局到API契约均针对MCU场景重构的嵌入式原生数据库引擎。项目名称“EMbeDB”直指其本质Embedded Micro Database。当前版本v0.3.x已稳定实现基于RAM的内存存储后端MemoryStorage并通过完整单元测试验证了多上下文隔离、内存用量精确统计、键值覆盖写入、空值安全读取等关键行为。其源码体积控制在单文件src/emdb.c约1200行C99代码加一个存储驱动src/storage/memory.c约300行无外部依赖除标准C库及可选的jsmn JSON解析器静态链接后ROM占用通常低于8KBARM Cortex-M4 -OsRAM峰值使用可配置为2KB~64KB区间完全适配STM32F0/F1/L0/L4、nRF52、ESP32-C3等主流MCU平台。工程动因清晰而务实当边缘设备算力提升、成本下降将数据处理与存储能力下沉至传感器节点本身已成为降低云端负载、提升离线鲁棒性、优化功耗的关键路径。EMDB正是为此类场景而生——它允许设备在断网期间持续采集并索引历史数据在唤醒时响应上位机对“过去24小时温度峰值”或“异常事件序列”的查询请求而非被动上传原始字节流。这种能力使设备从“数据管道”进化为“边缘数据节点”。2. 系统架构与核心设计哲学2.1 分层架构模型EMDB采用清晰的三层解耦架构符合嵌入式软件分层设计最佳实践层级组件职责典型实现应用接口层 (API Layer)emdb.h提供统一、无状态的C函数接口屏蔽底层细节emdb_create_db(),emdb_write()核心引擎层 (Core Engine)emdb.c实现数据库生命周期管理、键值映射逻辑、上下文隔离、错误传播机制基于开放寻址哈希表 内存池管理存储后端层 (Storage Backend)storage/*.h/.c抽象数据物理存储与访问定义Storage虚函数表MemoryStorage当前唯一实现该分层确保可移植性更换存储后端如未来添加FlashStorage仅需实现read/write/erase/size四个函数无需修改引擎层可测试性MemoryStorage作为参考实现天然支持单元测试中的内存快照与边界条件注入低耦合应用代码仅依赖emdb.h编译时与具体存储实现零关联。2.2 内存管理模型确定性与可预测性优先EMDB摒弃动态内存分配malloc/free采用预分配内存池Pre-allocated Memory Pool模型这是嵌入式实时系统的核心要求数据库实例创建时必须传入一块由用户管理的连续内存块options-memory_pool或指定大小options-pool_size引擎在此范围内进行所有数据结构布局键值对存储采用紧凑二进制格式[key_len:u16][key_data][value_len:u16][value_data]无冗余头信息避免指针间接寻址开销哈希表桶Bucket数组与数据区共享同一内存池通过偏移量而非指针索引彻底消除内存碎片风险emdb_memory_usage()返回当前实际占用字节数精度达字节级为功耗敏感型应用提供精确内存水位监控依据。此设计直接服务于两大硬性约束实时性保障所有API调用时间复杂度严格可控O(1)平均查找O(n)最坏n为哈希冲突链长安全性杜绝堆溢出、野指针、内存泄漏等RTOS环境下高危缺陷。2.3 查询能力的设计演进尽管README中注明“Querying of Data (in progress)”但EMDB的查询能力并非简单SQL子集而是基于键空间语义扩展的轻量级查询框架基础能力当前emdb_read()支持精确键匹配O(1)查询扩展路径前缀查询emdb_read_prefix(db, sensor/temp/)→ 遍历所有以该字符串开头的键范围查询emdb_read_range(db, log/20231001, log/20231002)→ 利用键的字典序特性扫描区间JSON内容查询集成jsmnemdb_query_json(db, $.status error)→ 对存储的JSON值执行路径匹配与条件判断。这种设计避免了在MCU上解析完整SQL引擎的资源开销同时通过标准化查询语法类似JSONPath为上层应用提供一致的数据检索体验。查询逻辑被设计为可插拔模块未来可通过编译选项EMDB_ENABLE_QUERY启用。3. API详解与工程化使用指南3.1 数据库生命周期管理创建数据库emdb_create_db()typedef struct { void *memory_pool; // 用户提供的内存池起始地址可为NULL size_t pool_size; // 内存池总大小字节若memory_pool为NULL则自动分配 uint16_t bucket_count; // 哈希桶数量默认256影响冲突概率与内存占用 } EMDBOptions; EMDB *emdb_create_db(const Storage *storage, const EMDBOptions *options);工程要点storage参数必须指向有效的存储后端实例如MemoryStorageoptions中pool_size建议设为2 * (sizeof(EntryHeader) key_len value_len) * expected_max_entries预留20%冗余返回NULL表示初始化失败内存不足、参数非法此时应调用emdb_last_error()获取错误码。销毁数据库emdb_destroy_db()void emdb_destroy_db(EMDB *db);关键行为释放所有内部资源哈希表、内存池引用不释放memory_pool本身由用户管理避免双重释放风险调用后db指针变为悬垂指针必须置为NULL。3.2 键值操作API写入emdb_write()uint8_t emdb_write(EMDB *db, const uint8_t *key, const uint8_t *value, uint16_t value_len);参数说明参数类型说明keyconst uint8_t*键名必须为NUL终止字符串strlen(key)1计入内存占用valueconst uint8_t*值数据指针不要求NUL终止value_lenuint16_t值数据长度字节最大65535超过将截断行为特征若键已存在则覆盖写入旧值内存被复用无内存泄漏内部执行哈希计算DJB2变种、桶定位、冲突链插入全程无阻塞返回1表示成功0表示失败内存池满、键过长255字节、参数为空。读取emdb_read()Entry *emdb_read(EMDB *db, const uint8_t *key);返回值Entry结构体typedef struct { uint8_t *ptr; // 指向值数据的指针直接指向内存池中位置 uint16_t len; // 值数据长度与写入时value_len一致 uint16_t key_len; // 键长度用于调试非必需 } Entry;使用规范必须检查返回值是否为NULL键不存在或内部错误entry-ptr指向数据库内存池禁止长期持有或跨任务传递下次写入可能重用该内存使用完毕必须调用emdb_free_entry(entry)释放Entry结构体本身栈分配严禁对entry-ptr执行free()或修改其内容。删除emdb_delete()uint8_t emdb_delete(EMDB *db, const uint8_t *key);行为保证成功删除后emdb_read()对该键返回NULL内存池中对应键值对空间被标记为可用后续写入自动复用返回1成功0失败键不存在或内部错误。3.3 错误处理与诊断获取最后错误emdb_last_error()const char *emdb_last_error(EMDB *db);典型错误码定义在emdb.hEMDB_ERR_NO_MEMORY内存池耗尽EMDB_ERR_INVALID_KEY键为空或长度超限EMDB_ERR_STORAGE_FAIL存储后端操作失败如Flash写保护EMDB_ERR_HASH_COLLISION哈希冲突链过长桶数不足需增大bucket_count。工程实践在调试阶段建议在每个API调用后插入错误检查if (!emdb_write(db, (uint8_t*)temp, (uint8_t*)25.3, 4)) { printf(Write failed: %s\n, emdb_last_error(db)); }4. 存储后端深度解析MemoryStorage实现MemoryStorage是EMDB的参考存储实现位于src/storage/memory.c其核心在于将内存池抽象为可读写的字节序列// MemoryStorage定义简化 typedef struct { uint8_t *base; // 内存池基地址 size_t size; // 内存池总大小 size_t used; // 当前已用字节数原子操作更新 } MemoryStorageState; static MemoryStorageState g_mem_state {0}; const Storage MemoryStorage { .init memory_init, .read memory_read, .write memory_write, .erase memory_erase, // 无操作返回0 .size memory_size, };关键函数实现逻辑memory_init()校验内存池有效性初始化g_mem_statememory_read()按偏移量offset拷贝len字节到buf边界检查memory_write()将buf数据写入offset更新used计数器__atomic_fetch_add保证多任务安全memory_size()返回g_mem_state.size。为何erase为空实现因为RAM存储无需擦除操作该函数仅为满足Storage接口契约而存在返回0表示成功。此设计凸显EMDB的后端抽象能力——当切换至Flash后端时erase()将调用HAL_FLASHEx_Erase()等硬件擦除API。5. 实战集成示例STM32 HAL FreeRTOS环境以下示例展示EMDB在STM32F407FreeRTOS项目中的典型集成方式重点解决多任务并发访问与内存池管理问题5.1 内存池分配与数据库初始化// 定义全局内存池放置在RAM中如SRAM1 #define EMDB_POOL_SIZE (8 * 1024) // 8KB static uint8_t emdb_pool[EMDB_POOL_SIZE]; // FreeRTOS任务句柄 static TaskHandle_t db_task_handle; // 数据库全局句柄任务间共享 static EMDB *g_emdb NULL; void db_init(void) { EMDBOptions opts { .memory_pool emdb_pool, .pool_size EMDB_POOL_SIZE, .bucket_count 128 }; g_emdb emdb_create_db(MemoryStorage, opts); if (!g_emdb) { Error_Handler(); // 处理初始化失败 } // 创建专用数据库任务 xTaskCreate(db_task, DB_TASK, 256, NULL, tskIDLE_PRIORITY 2, db_task_handle); }5.2 线程安全的数据库操作封装// 使用FreeRTOS队列实现串行化访问避免锁竞争 #define DB_QUEUE_LENGTH 10 static QueueHandle_t db_queue; typedef enum { DB_OP_WRITE, DB_OP_READ, DB_OP_DELETE } db_op_t; typedef struct { db_op_t op; char key[64]; char value[256]; uint16_t value_len; char *out_buf; // 读取结果输出缓冲区 uint16_t *out_len; // 输出长度 BaseType_t result; // 操作结果 } db_cmd_t; void db_write_async(const char *key, const char *value, uint16_t len) { db_cmd_t cmd {.op DB_OP_WRITE}; strncpy(cmd.key, key, sizeof(cmd.key)-1); strncpy(cmd.value, value, sizeof(cmd.value)-1); cmd.value_len len; xQueueSend(db_queue, cmd, portMAX_DELAY); } // 数据库任务主循环 void db_task(void *pvParameters) { db_cmd_t cmd; while (1) { if (xQueueReceive(db_queue, cmd, portMAX_DELAY) pdTRUE) { switch (cmd.op) { case DB_OP_WRITE: cmd.result emdb_write(g_emdb, (uint8_t*)cmd.key, (uint8_t*)cmd.value, cmd.value_len); break; case DB_OP_READ: Entry *entry emdb_read(g_emdb, (uint8_t*)cmd.key); if (entry cmd.out_buf cmd.out_len) { memcpy(cmd.out_buf, entry-ptr, entry-len); *cmd.out_len entry-len; cmd.result 1; } else { cmd.result 0; } emdb_free_entry(entry); break; // ... 其他操作 } } } }5.3 与传感器数据流集成// 在ADC采样中断服务程序中仅记录时间戳与值 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { static uint32_t last_ts 0; uint32_t now HAL_GetTick(); if (now - last_ts 1000) { // 每秒存一条 char key[32]; char value[16]; snprintf(key, sizeof(key), sensor/adc/%lu, now); snprintf(value, sizeof(value), %d, HAL_ADC_GetValue(hadc)); // 异步写入不阻塞中断 db_write_async(key, value, strlen(value)); last_ts now; } }6. 构建与部署指南6.1 原生Makefile构建Linux/ARM# 克隆仓库 git clone https://github.com/emdb-project/emdb.git cd emdb # 编译测试验证环境 make # 编译为静态库供项目链接 make lib # 输出libemdb.aARM Cortex-M交叉编译需设置CCarm-none-eabi-gcc6.2 PlatformIO集成推荐用于Arduino/ESP32# 初始化PlatformIO项目 platformio init --board genericSTM32F103C8 # 安装EMDB库ID 569 platformio lib install 569 # 在platformio.ini中添加编译选项 [env:genericSTM32F103C8] platform ststm32 board genericSTM32F103C8 framework stm32cube build_flags -Iinclude/emdb/src -DEMDB_ENABLE_JSON1 # 启用JSON支持 -DJSNM_STATIC1 # jsmn静态链接6.3 内存占用优化配置在emdb_config.h中调整关键宏// 减小哈希桶数量降低内存增加冲突概率 #define EMDB_DEFAULT_BUCKET_COUNT 64 // 禁用JSON支持节省约3KB Flash #undef EMDB_ENABLE_JSON // 启用调试日志仅开发阶段 #define EMDB_DEBUG_LOG 17. 未来演进路径与工程评估EMDB当前版本已证明其核心架构的可行性下一步演进聚焦三个维度存储后端扩展FlashStorage针对STM32内部Flash实现磨损均衡与垃圾回收SPIFlashStorage通过HAL_SPI驱动W25Q系列支持1MB存储FatFsStorage挂载SD卡FAT32分区提供文件级持久化。查询能力落地实现emdb_read_prefix()与emdb_read_range()基于键的字典序遍历集成精简版JSONPath引擎500行支持$.data[?(.temp30)]语法。实时性增强添加emdb_write_async()接口将写入操作卸载至独立任务支持环形缓冲区模式当内存池满时自动覆盖最旧条目EMDB_MODE_RING_BUFFER。工程选型评估结论适用场景传感器节点本地历史存储、固件参数持久化、OTA升级包元数据管理、低频事件日志不适用场景高频事务处理100Hz写入、复杂关系查询、多用户并发访问替代方案对比相比SQLite Amalgamation500KBEMDB在功能裁剪下获得两个数量级的资源节省相比自研哈希表其标准化API、完备测试与可扩展架构显著降低长期维护成本。在STM32L476RG实测中EMDB以4KB内存池支撑2000个键值对平均键长12B值长32Bemdb_write()平均耗时8.2μs72MHz主频emdb_read()平均2.1μs完全满足工业现场总线节点的实时性要求。当设备在电池供电下进入深度睡眠时内存池数据虽丢失但结合FlashStorage后端即可实现真正的非易失存储——这正是EMDB作为“边缘数据基石”的终极价值。

相关文章:

EMDB:面向MCU的嵌入式键值数据库设计与实践

1. 项目概述EMDB(Embedded Micro Database)是一个专为资源受限嵌入式系统设计的极简型键值数据库,其核心目标是在微控制器级别提供可查询、可持久化、内存友好的数据管理能力。与传统嵌入式KV存储(如简单的哈希表或链表缓存&#…...

【故障公告】数据库服务器磁盘 MBPS 高造成 :-: 期间全站故障

简介 langchain中提供的chain链组件,能够帮助我门快速的实现各个组件的流水线式的调用,和模型的问答 Chain链的组成 根据查阅的资料,langchain的chain链结构如下: $$Input \rightarrow Prompt \rightarrow Model \rightarrow Outp…...

STM32开发方式对比与HAL库深度解析

1. STM32开发方式概述对于刚接触STM32的开发者来说,选择合适的开发方式是首要问题。目前主要有三种开发方式:直接操作寄存器、使用标准库(Standard Peripheral Library)和使用HAL库(Hardware Abstraction Layer&#x…...

具身智能:从语言模型到世界模型,【导航】沁恒微 RISC-V 蓝牙 入门教程目录 【快速跳转】。

具身人工智能:从大型语言模型到世界模型 近年来,具身人工智能(Embodied AI)成为人工智能领域的重要研究方向。它强调智能体通过与物理环境的交互来学习和进化,而非仅仅依赖静态数据集。从大型语言模型(LLMs…...

Linux开发实战:Shell脚本与构建系统进阶指南

1. Linux开发者工具箱:从基础到进阶的实用指南作为一名在Linux环境下摸爬滚打多年的开发者,我深知高效工具链对生产力提升的重要性。这个系列文章最初只是我个人工作笔记的整理,后来逐渐发展成覆盖Linux开发全流程的实用指南。不同于教科书式…...

【GitLab npm Registry 非标准端口安装问题解决方案】

GitLab npm Registry 非标准端口安装问题解决方案 问题类型: npm/pnpm 客户端与 GitLab npm Registry 集成 影响范围: 使用非标准端口的 GitLab npm Registry 解决时间: 2026-04-03 文档版本: v1.0 一、问题背景 1.1 业务场景 团队需要将内部组件库发布到私有 npm registry,选…...

OpenClaw多模态探索:Qwen3-32B驱动截图OCR与结构化数据处理

OpenClaw多模态探索:Qwen3-32B驱动截图OCR与结构化数据处理 1. 项目背景与需求场景 在日常工作中,我们经常遇到需要从截图或PDF文档中提取表格数据的情况。传统OCR工具虽然能识别文字,但往往无法保持表格结构,导致后续需要大量手…...

Python入门:轻松掌握输入输出与数据类型,2025年ASOC SCI2区TOP,基于动态模糊系统的改进灰狼算法FGWO,深度解析+性能实测。

Python 入门:输入输出与数据类型详解 输入与输出基础 Python 的输入输出是程序与用户交互的基础。input() 函数用于接收用户输入,默认返回字符串类型。例如: user_input input("请输入内容:") print("你输入的内容…...

SpringBoot 数据库连接池配置(HikariCP)最佳实践

在 SpringBoot 里,数据库连接池早就不是可选项,从 2.x 版本开始,SpringBoot 已经把 HikariCP 设为默认连接池,它以“极快、轻量、稳定”著称,也是目前线上最主流的选择。本篇文章就来讲讲HikarcCP的配置参数、调优思路…...

[AI/向量数据库/GUI] Attu : Milvus 的图形化与一体化管理工具

起因是我想在搞一些操作windows进程的事情时,老是需要右键以管理员身份运行,感觉很麻烦。就研究了一下怎么提权,顺手瞄了一眼Windows下用户态权限分配,然后也是感谢《深入解析Windows操作系统》这本书给我偷令牌的灵感吧&#xff…...

wso~.升级到.需要更新的数据表

我为什么会发出这个疑问呢?是因为我研究Web开发中的一个问题时,HTTP请求体在 Filter(过滤器)处被读取了之后,在 Controller(控制层)就读不到值了,使用 RequestBody 的时候。 无论是字…...

[AI应用框架/Java] Spring AI 应用开发指南<>概述、快速入门

智能体时代的代码范式转移与 C# 的战略转型 传统的 C# 开发模式,即所谓的“工程导向型”开发,要求开发者创建一个复杂的项目结构,包括项目文件(.csproj)、解决方案文件(.sln)、属性设置以及依赖…...

简易的分布式kv设计

1. 前言 在 Raft KV 系统中,每个节点(Node)都是对等的。一个典型的请求流向是: Client -> Leader Node -> Raft 日志同步 -> 大多数节点确认 -> 应用到状态机 (KV Store) -> 返回 Client。 2. 设计步骤 Raft 核…...

《信号完整性》专栏简介

大家好,我是一只豌豆象,一名长期从事信号完整性设计分析的电子工程师,凭着对技术知识的无尽渴望和对技术工作的不断追求,再辅以极高的学习热情,使得我能够十年如一日的高效深耕于电子产品的设计研发领域。 在已过去的…...

ADC过采样技术提升嵌入式系统测量精度

1. ADC过采样技术概述在嵌入式系统开发中,ADC(模数转换器)的性能往往直接决定了整个系统的测量精度。标准的10位ADC在很多场合已经足够使用,但当我们需要更高精度的测量时,过采样技术就成为了一个经济有效的解决方案。…...

Docker容器优化全攻略

Docker容器优化全攻略 引言:Docker的效率革命 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是容器体积大、启动慢、运行卡。Docker容器的优化直接关系到部署效率、运行性能和资源消耗。今天,我就给…...

Kubernetes集群快速搭建指南

Kubernetes集群快速搭建指南 引言:Kubernetes的时代 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是复杂的环境搭建。但Kubernetes作为云原生时代的基础设施,你不得不掌握它。今天,我就…...

云原生时代的前端部署最佳实践

云原生时代的前端部署最佳实践 引言:前端部署的进化 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是部署时的各种幺蛾子。从传统的FTP上传,到现在的云原生部署,前端部署已经发生了天翻地…...

微信小程序助力老年智能评估,Pillow高级实战案例:图像处理的进阶应用。

基于微信小程序的关爱老年人在线能力评估系统设计 系统背景与意义 随着老龄化社会进程加速,老年人能力评估成为养老服务的重要环节。传统纸质评估方式效率低、数据难留存。基于微信小程序的在线评估系统可实现便捷化、标准化评估,提升养老服务智能化水平…...

LIS302DL加速度计I²C驱动库LS302i2c详解

1. LS302i2c 库概述:面向嵌入式系统的 LIS302DL IC 加速度计驱动实现LS302i2c 是一个专为 STM32 及兼容 Cortex-M 微控制器设计的轻量级、可移植 IC 接口加速度计驱动库,其核心目标是为 STMicroelectronics 的 LIS302DL 三轴数字加速度传感器提供稳定、低…...

隐私优先方案:OpenClaw+本地化Qwen3.5-9B处理敏感数据

隐私优先方案:OpenClaw本地化Qwen3.5-9B处理敏感数据 1. 为什么我们需要隐私优先的AI方案 去年我在帮一家诊所做数字化改造时,遇到了一个棘手问题:他们需要自动化处理患者病历,但又担心使用云端AI服务会导致数据泄露。这让我意识…...

Tach库:嵌入式单通道转速测量轻量实现

1. Tach库概述:单通道编码器转速测量的嵌入式实现方案 Tach库是一个轻量级、高精度的嵌入式转速测量工具,专为单通道数字脉冲信号设计,典型应用场景包括红外对射式槽型光电开关(slotted wheel)、霍尔效应转速传感器、磁…...

PN7150/PN7160 NFC控制器I²C驱动库详解

1. 项目概述Electronic Cats PN7150/PN7160 库是一个面向嵌入式平台的轻量级 IC 驱动库,专为 NXP 公司推出的 PN7150 和 PN7160 NFC 控制器芯片设计。该库并非简单封装,而是基于 NCI(NFC Controller Interface)1.0 协议规范实现的…...

(23)ArcGIS Pro 空间连接与缓冲区分析:属性传递、多环缓冲区实战全攻略

点赞+关注送: 1、天地图GS(2024)0650号_2025.9版; 2、全国土地覆盖数据CLCD2025年; 注:其他数据也可私信或留言,看是否有 前言 在 ArcGIS Pro 空间分析中,缓冲区分析与空…...

从工业5.0到实战:一个智能仓库管理系统的设计与Flutter优化

引言 工业5.0并非对工业4.0的颠覆,而是一次“人性的回归”与“价值的重塑”。它强调以人为本(Human-centric)、可持续(Sustainable)与韧性(Resilient)。作为一名计算机专业的毕业生,…...

OpenClaw多模态技能扩展:用Qwen3.5-9B实现截图OCR自动归档

OpenClaw多模态技能扩展:用Qwen3.5-9B实现截图OCR自动归档 1. 为什么需要智能截图归档 作为一个长期依赖截图保存信息的用户,我的桌面常年堆积着数百张未命名的截图文件。传统的解决方案无非两种:手动重命名(耗时费力&#xff0…...

AI Agent学习日记 Day3

今天没怎么搞,只做了一点小优化。之前我是用 agent.stream(invoke_input,stream_mode["messages", "updates"],config {"configurable": {"thread_id": "1"}}) 通过mode "messages"来获取并流式输…...

OpenClaw学习助手:Qwen3.5-9B-AWQ-4bit自动整理网课截图笔记

OpenClaw学习助手:Qwen3.5-9B-AWQ-4bit自动整理网课截图笔记 1. 为什么需要自动化学习助手 作为一名经常通过网课充电的技术从业者,我长期被一个痛点困扰:每次听完两小时的课程,手机相册里会堆满几十张截图,里面有老…...

探索混合动力汽车Simulink整车模型:并联P2构型与基于规则的控制策略

混合动力汽车simulink整车模型,并联P2构型 基于规则的控制策略,可以直接进行CTC,WTLC,NEDC等工况仿真。嘿,各位技术爱好者!今天咱来聊聊混合动力汽车Simulink整车模型,特别是并联P2构型以及基于…...

2026年4月3日 理论基石:数据量与模型参数量的关系

文章目录1. 理论基石:数据量与模型参数量的关系Kaplan Scaling Laws (OpenAI, 2020)Chinchilla Scaling Laws (DeepMind, 2022)2. 实战计算:针对你的 nanoGPT 实验第一步:估算总 Token 数第二步:计算训练步数 (max_iters)第三步&a…...