ext4_dirty_inode与ext4_do_update_inode函数详解

ext4日志系统分析(一) 一、背景ext4文件系统用的是jbd2日志系统。本篇博客从内核源码着手,大致分析jbd2日志系统。二、源码分析我这里用的是source insight工具来分析linux内核的源码。 内核版本为3.10.0。 首先我们搜索一下jbd2关键字。可以看到如下图所示: 可以看到,在fs/jbd2中存在6个文件。这个fs/jbd2中存的就是jbd2日志系统的代码。 一步一步来,先看看插入jbd2 阅读详情

一、ext4_dirty_inode

定义在fs/ext4/inode.c中,其内容如下:

void ext4_dirty_inode(struct inode *inode, int flags)
{
    handle_t *handle;

    if (flags == I_DIRTY_TIME)

        return;

    handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);

    if (IS_ERR(handle))

        goto out;

    ext4_mark_inode_dirty(handle, inode);

    ext4_journal_stop(handle);

out:
    return;
}

在ext4_dirty_inode函数中,一共调用了三个函数,分别为:

①ext4_journal_start函数

②ext4_mark_inode_dirty函数

③ext4_journal_stop函数

在ext4_dirty_inode中定义了handle_t *handle,然后将ext4_journal_start函数的返回值赋值给了这个handle,这个handle再作为参数被传递进ext4_mark_inode_dirty函数中。

1、ext4_journal_start函数

上面讲述了ext4_journal_start返回了handle,ext4_journal_start函数涉及ext4文件系统使用的jbd2日志模块,它将启用一个新的日志handle(日志原子操作)并将应该同步的inode元数据block向日志jbd2模块transaction进行提交(注意不会立即写日志和回写)。其中ext4_journal_start函数会简单判断一下ext4文件系统的日志执行状态最后直接调用jbd2__journal_start来启用日志handle。

jdb2__journal_start函数定义在linux\jdb2\transaction.c文件中,这属于jdb2模块的相关内容。

2、ext4_mark_inode_dirty函数

在ext4_mark_inode_dirty函数中内容还是挺多的,其内容如下:

int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode)
{
       struct ext4_iloc iloc;
       struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
       static unsigned int mnt_count;
       int err, ret;

       might_sleep();

       trace_ext4_mark_inode_dirty(inode, _RET_IP_);

       err = ext4_reserve_inode_write(handle, inode, &iloc);

       if (ext4_handle_valid(handle) &&

           EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize &&

           !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) {

              /*

               * We need extra buffer credits since we may write into EA block

               * with this same handle. If journal_extend fails, then it will

               * only result in a minor loss of functionality for that inode.

               * If this is felt to be critical, then e2fsck should be run to

               * force a large enough s_min_extra_isize.

               */

              if ((jbd2_journal_extend(handle,
                          EXT4_DATA_TRANS_BLOCKS(inode->i_sb))) == 0) {
                     ret = ext4_expand_extra_isize(inode,
                                                sbi->s_want_extra_isize,

                                                iloc, handle);

                     if (ret) {
                            ext4_set_inode_state(inode,
                                               EXT4_STATE_NO_EXPAND);

                            if (mnt_count !=
                                   le16_to_cpu(sbi->s_es->s_mnt_count)) {

                                   ext4_warning(inode->i_sb,

                                   "Unable to expand inode %lu. Delete"

                                   " some EAs or run e2fsck.",

                                   inode->i_ino);
                                   mnt_count =
                                     le16_to_cpu(sbi->s_es->s_mnt_count);
                            }
                     }
              }
       }

       if (!err)
             err = ext4_mark_iloc_dirty(handle, inode, &iloc);

       return err;
}

首先,在ext4_mark_inode_dirty函数中调用了ext4_reserve_inode_write,该函数内容如下:

int ext4_reserve_inode_write(handle_t *handle, struct inode *inode, struct ext4_iloc *iloc)

{

       int err;

       err = ext4_get_inode_loc(inode, iloc);

       if (!err) {

              BUFFER_TRACE(iloc->bh, "get_write_access");

              err = ext4_journal_get_write_access(handle, iloc->bh);

              if (err) {

                     brelse(iloc->bh);

                     iloc->bh = NULL;

              }

       }

       ext4_std_error(inode->i_sb, err);

       return err;

}

在这个函数里面首先调用了ext4_get_inode_loc函数,返回值为err,如果返回为0,则调用ext4_journal_get_write_access函数,返回值赋给err。首先进入到ext4_get_inode_loc函数中看其具体实现:

int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc)
{

       /* We have all inode data except xattrs in memory here. */

       return __ext4_get_inode_loc(inode, iloc,

              !ext4_test_inode_state(inode, EXT4_STATE_XATTR));

}

ext4_get_inode_loc顾名思义,该函数可能要做的工作就是get inode location,进入到__ext4_get_inode_loc查看是否如此。__ext4_get_inode_loc同样定义在fs\ext4\inode.c中,其中有一个重要的数据结构struct ext4_iloc:

struct ext4_iloc
{
       struct buffer_head *bh;
       unsigned long offset;
       ext4_group_t block_group;
};

该结构用于描述一个inode在磁盘和内存中的精确位置。在__ext4_get_inode_loc中基本就是在为ext4_iloc结构赋值,得到buffer_head。__ext4_get_inode_loc执行成功,返回值为0,那么必定会执行ext4_journal_get_write_access函数。

该函数实现定义在fs\ext4\ext4_jdb2.c中:

int __ext4_journal_get_write_access(const char *where, unsigned int line,
                                handle_t *handle, struct buffer_head *bh)
{

       int err = 0;

       might_sleep();
       if (ext4_handle_valid(handle)) {

              err = jbd2_journal_get_write_access(handle, bh);
              if (err)
                     ext4_journal_abort_handle(where, line, __func__, bh,
                                            handle, err);
       }

       return err;
}

其中调用了jdb2_journal_get_write_access函数,现在进入到该函数中查看该函数的具体实现。该函数定义在fs\jdb2\transaction.c中,其内容如下:

int jbd2_journal_get_write_access(handle_t *handle, struct buffer_head *bh)
{
       struct journal_head *jh;
       int rc;

       if (jbd2_write_access_granted(handle, bh, false))
              return 0;


       jh = jbd2_journal_add_journal_head(bh);

       /* We do not want to get caught playing with fields which the

        * log thread also manipulates.  Make sure that the buffer

        * completes any outstanding IO before proceeding. */

       rc = do_get_write_access(handle, jh, 0);

       jbd2_journal_put_journal_head(jh);

       return rc;
}

该函数用于获取写权限。

获取写权限之后,简单做一些判断操作,最后再调用ext4_mark_inode_dirty函数,在该函数中又调用了ext4_do_update_inode,这两个函数在下一节进行讲解。

总结:

ext4_mark_inode_dirty函数会调用ext4_get_inode_loc获取inode元数据所在的buffer

 head映射block,按照标准的日志提交流程jbd2_journal_get_write_access(获取写权限)-> 对元数据raw_inode进行更新 -> jbd2_journal_dirty_metadata(设置元数据为脏并添加到日志transaction的对应链表中);

调用链如下所示:

ext4_mark_inode_dirty

——ext4_reserve_inode_write

————ext4_get_inode_loc获取ext4_iloc

————ext4_journal_get_write_access获取写权限

——————jbd2_journal_get_write_access

——ext4_mark_iloc_dirty

————ext4_do_update_inode

3、ext4_journal_stop函数

最后ext4_journal_stop->jbd2_journal_stop调用流程结束这个handle原子操作。这样后面日志commit进程会对日志的元数据块进行提交(注意,这里并不会立即唤醒日志commit进程启动日志提交动作,启用largefile特性除外)。

二、ext4_do_update_inode

ext4_do_update_inode定义在fs\ext4\inode.c中,作用是将内存中的inode信息赋值给表示磁盘inode信息的on-disk inode,即ext4_inode_info->ext4_inode,但是这个ext4_inode不是立即刷回的。

对于ext4_do_update_inode采用“溯源法”,查看其上层调用,使用Source Insight查看内核源码,通过搜索ext4_do_update_inode可得如下图片中的信息。

对于ext4_do_update_inode的调用只能来自,ext4_mark_iloc_dirty函数,所以下一个需要了解的函数就是ext4_mark_iloc_dirty。

在ext4_do_update_inode中,还调用了ext4_handle_dirty_metadata()函数,用于将handle添加到transaction中。

1、ext4_mark_iloc_dirty

该函数定义在fs\ext4\inode.c中,其内容如下:

int ext4_mark_iloc_dirty(handle_t *handle,
                      struct inode *inode, struct ext4_iloc *iloc)
{
       int err = 0;

       if (IS_I_VERSION(inode))

              inode_inc_iversion(inode);

       /* the do_update_inode consumes one bh->b_count */

       get_bh(iloc->bh);

       /* ext4_do_update_inode() does jbd2_journal_dirty_metadata */

       err = ext4_do_update_inode(handle, inode, iloc);

       put_bh(iloc->bh);

       return err;
}

从该函数内容可以看出,函数并不复杂,通过get_bh获取到buffer_head,然后通过函数ext4_do_update_inode更新ext4_inode。从代码的注释可以得知如下信息:

(1)do_update_inode消耗一个bh-> b_count

(2)ext4_do_update_inode()does jbd2_journal_dirty_metadata

(3)该函数的调用者必须事先调用ext4_reserve_inode_write()函数,确保调用者已经获得了对iloc->bh的写权限。

2、总结

ext4_dirty_inode

——ext4_mark_inode_dirty

————ext4_reserve_inode_write

——————ext4_get_inode_loc获取ext4_iloc

——————ext4_journal_get_write_access获取写权限

————————jbd2_journal_get_write_access

————ext4_mark_iloc_dirty

——————ext4_do_update_inode

vm内核参数之内存脏页dirty_writeback_centisecs和dirty_expire_centisecs 注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4 1、背景 在《BDI writeback脏页回写》中我们了解了BDI的一些基本结构以及初始化和一些触发路径,现在我们要更深入了解下脏页的writeback,一个是脏页什么时候会被处理,另一个是多久会触发脏页的writeback。 2、脏页形成路径 脏页由写操作引入,毕竟读操作不会引起数据的不一致性。不管应用层以什么方式将数据变脏,最终都会调用__mark_inode_dirty将inode标记dirty。而调用__mark_ino 阅读详情

相关推荐

Ubuntu 20.04 swapfile 配置实战:从创建、调优到高负载验证

swap 是 Linux 内存管理的关键机制,本质是内核在物理内存不足时将非活跃页暂存至磁盘的虚拟内存扩展技术。其原理依赖于页置换算法(如LRU)、swap 分区或 swap 文件的底层 I/O 调度,以及 vm.swappiness 等内核参数协同调控。现代发行版如 Ubuntu 20.04 默认采用 swapfile 方案,兼顾 SSD 寿命、灵活性与启动效率,但默认仅配置 1GB 且未优化优先级与压缩策略,极易在 VINS-MONO、ROS2、Blender 或多容器场景中触发 OOM killer。

weixin_33874713的博客 453

性能分析之解决 jbd2 引起 IO 高问题

文章目录一、前言二、预备知识1、jbd2 是什么?2、检查是否存在 jbd2 进程3、检查文件系统的功能三、问题现象四、问题原因五、解决办法1、方案一2、方案二3、方案三4、方案四六、bug 的根源七、影响版本 一、前言 之前遇到过 jbd2 引起 IO 高的问题,直接关掉了日志的功能解决的。最近又见类似问题,这里重新整理下对 jbd2 的内容。 二、预备知识 1、jbd2 是什么? The Journaling Block Device (JBD) provides a filesystem-indep

7DGroup,让技术更有价值! 1万+

Linux操作系统核心架构与系统管理实战指南

Linux作为开源的类Unix操作系统内核,采用模块化设计支持多用户、多任务操作,其核心架构分为内核空间与用户空间,通过系统调用实现交互。理解Linux的进程管理、内存管理和文件系统等核心子系统,对于系统性能优化和故障排查至关重要。在实际工程应用中,从用户权限管理到软件包安装,再到网络配置和防火墙设置,掌握这些基础管理技能能有效提升运维效率。通过Shell脚本编程和性能监控工具的使用,可以进一步实现自动化运维和系统调优。对于企业级应用,Linux的安全加固和容器化部署已成为现代IT基础设施的关键技术。

weixin_34342207的博客 339

ext4文件系统之文件查找ext4_lookup函数源码解析

网上讲解ext4的文章挺多的,但是讲解ext4源码的文章很少。本文首先介绍ext4磁盘布局,然后讲解文件查找函数ext4_lookup源码

dongzhiyan_hjp 3462

从Kernel Panic到CUDA Kernel:深入解析操作系统内核的设计哲学与工程实践

内核(Kernel)是操作系统的核心组件,负责管理系统资源、提供硬件抽象层,并确保系统的安全与稳定运行。其核心原理在于通过划分用户空间与内核空间,利用CPU提供的不同特权级别(如Ring 0和Ring 3),实现对硬件和关键资源的受控访问。这种设计带来了显著的技术价值:它通过集中管理保障了系统安全,防止应用程序间的相互干扰;同时,通过减少不必要的上下文切换和权限检查,为需要直接硬件交互的任务(如GPU计算、网络包处理)提供了极致的性能基础。在应用场景上,无论是Linux的宏内核、VxWorks的微内核,还是

weixin_30570101的博客 495

CVS、Subversion 与 Git 版本控制底层原理深度解析

版本控制系统是软件开发的基础设施,其核心在于数据模型设计与协作语义约定。CVS 基于文件级 RCS 补丁链,依赖时间戳与显式加锁,导致无原子提交和分支脆弱;Subversion 引入全局修订号与树状快照,实现原子事务与真分支,但强耦合中心服务器;Git 采用内容寻址的 DAG 对象图,通过 SHA-1 哈希保障状态一致性,支撑分布式、离线操作与历史重写能力。这些差异直接决定冲突解决方式、分支开销、迁移成本及协同可靠性。理解 CVS 的 strict 锁机制与 git 的 staging 区设计,是规避日常

as2886089的博客 360

Debian 8 Swap 配置实战:swapfile 方案与内核兼容性避坑指南

Swap 是 Linux 内存管理的关键机制,本质是为内核提供可控的页回收出口,支撑 OOM 防御与内存超分容错。其原理依赖内核版本、文件系统特性及 init 系统调度时机,在老旧发行版中尤为敏感。Debian 8(Jessie)基于 Linux 3.16 内核与 SysV init,存在 swapfile 格式签名兼容性、fstab 解析陷阱、启动时序依赖等独特约束。相比 Swap 分区,swapfile 因在线创建、规避分区调整风险、适配 checkroot.sh 启动阶段等优势,成为该环境更可靠的选择

weixin_33694620的博客 412

从零到一:手把手教你搭建高可用Linux NFS文件共享服务

本文详细介绍了如何从零开始搭建高可用Linux NFS文件共享服务,包括环境准备、服务端与客户端配置、性能优化及安全加固等关键步骤。通过实战案例和故障排查技巧,帮助读者快速掌握NFS部署要点,适用于多服务器共享资源、集中式日志存储等场景,提升企业级文件共享解决方案的可靠性与性能。

weixin_34320724的博客 438

LINUX文件系统

http://blog.chinaunix.net/uid-2469966-id-2595309.html 本章主要描叙Linux核心对文件系统的支持, 虚拟文件系统(VFS)以及Linux核心对实际文件系统的支持。 Linux的最重要特征之一就是支持多种文件系统。这样它更加灵活并可以和许多其它种操作系统共存。在本文写作时Linux已经支持15种文件系统: ext,ext2,xi

xyyangkun的专栏 978

Linux下fastai Chapter 2实战排障:DataBlock与CUDA深度优化

DataBlock是fastai构建数据流水线的核心抽象,其在Linux环境下的行为受文件系统权限、路径解析机制、多进程调度及CUDA内存管理等底层因素深刻影响。理解其依赖链——从Python的pathlib遍历、PIL图像解码,到torch DataLoader的fork子进程与cuMemAlloc显存分配——是解决FileNotFoundError、PermissionError和CUDA out of memory等问题的前提。Linux原生环境不隐藏系统细节,反而暴露了PyTorch、PIL、Ope

weixin_34337381的博客 535

linux磁盘IO打满时,write文件被卡住问题排查

linux磁盘IO打满时,write文件被卡住问题排查

John_ToStr的博客 1464

达梦数据库 DM8 国产化环境部署:银河麒麟 V10 系统参数调优与安全加固 5 项关键配置

本文详细介绍了达梦数据库 DM8 在银河麒麟 V10 系统上的国产化环境部署,重点解析了5项关键系统参数调优与安全加固配置,包括文件句柄优化、SELinux策略、存储I/O调度、内核参数调优及安全权限隔离,帮助提升数据库性能40%以上并满足等保要求。

weixin_30420305的博客 420

【信息科学与工程学】【产品体系】计算机科学与自动化——第一百八十九篇 操作系统内核(微内核/宏内核)函数与算法05

Cgroup BPF 与 XDP/eBPF 的协同——这是容器网络(如 Cilium)和按身份做网络策略的核心机制。需要先厘清三者关系:编号类型领域内核类型(含版本)内核中的函数/算法/模块模块的调用关系模块/函数/算法逐步推理思考的数学表达式及参数列表及参数数值设计模块的 C/C++/其他代码关联知识Cg01​算法cgroup/skb egress 按 cgroup 身份丢包宏内核(Linux 4.10+) + + 进程在 cgroup 内 → → 执行 cgroup egress BPF 程序;

weixin_49199313的博客 22

Ubuntu 20.04 LEMP生产级调优:Nginx、MySQL、PHP协同优化指南

LEMP(Linux+Nginx+MySQL+PHP)是Web服务的经典技术栈,其核心价值不在于组件安装,而在于四者在高并发、低延迟、强稳定性场景下的深度协同。理解Nginx的location匹配机制与反向代理连接复用原理,掌握MySQL 8.0字符集兼容性配置与InnoDB表碎片在线治理方法,厘清PHP-FPM进程模型与OPcache预热逻辑,并结合Ubuntu 20.04系统级限制(如systemd资源约束、内核网络参数、EXT4挂载选项)进行全局调优,才能构建真正可承载真实业务流量的生产环境。本文聚焦

weixin_30430169的博客 383

Spec-Kit实战:用‘规范驱动开发’重构一个老旧Node.js项目(避坑指南)

本文详细介绍了如何使用Spec-Kit工具通过‘规范驱动开发’(SDD)重构老旧Node.js项目。从逆向工程提取规范到增量改造策略,再到避免典型陷阱,提供了实战指南和避坑技巧,帮助开发者高效实现架构现代化,显著提升代码质量和维护效率。

weixin_42525582的博客 555

DDR4协议规范之(一)DDR4结构和寻址

DDR4 SDRAM结构和寻址DDR4 SDRAM的封装和寻址新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 DDR4 SDRAM的封装和寻址 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习

YJFeiii的博客 3万+

CentOS 7 Swap配置全指南:文件vs分区、fstab陷阱与内核调优

Swap(交换空间)是Linux内存管理的关键机制,用于扩展物理内存、支撑休眠功能并提供OOM防护。其核心原理是将不活跃内存页暂存至磁盘,由内核通过swappiness等参数动态调度。技术价值在于平衡性能、稳定与硬件寿命——尤其在SSD普及后,swap文件方案因灵活扩容和磨损均衡成为VMware等虚拟化环境首选。典型应用场景包括内存突发负载缓冲、KVM宿主机故障隔离、以及hibernate支持。本文聚焦CentOS 7的swap设计哲学,详解swap文件创建、fstab安全配置、initramfs适配及vm

weixin_36250541的博客 468

从零开始:H20服务器上DeepSeek R1 671B大模型部署与压力测试全攻略

最近,我有幸在工作中接触到了DeepSeek R1 671B模型,这是目前中文开源领域参数量最大的高质量模型之一。DeepSeek团队在2024年推出的这款模型,以其惊人的6710亿参数量和出色的推理性能,引起了业界广泛关注。作为一名AI基础设施工程师,我有机会在H20服务器上部署这个庞然大物,并对其进行了全面的压力测试。这篇文章将详细记录我的部署过程和性能测试方法,希望能为大家提供一些参考。💡为什么选择DeepSeek R1?超大规模参数量(671B)优秀的中英文理解能力开源可商用的许可证。

wangli的博客 1万+

Linux新手入门与高效使用技巧全指南

Linux作为开源操作系统的代表,其核心优势在于直接控制硬件的能力和高度可定制性。通过虚拟化技术如VirtualBox,用户可以轻松创建Linux开发环境,而掌握终端操作、文件管理和系统监控等基础技能是提升效率的关键。在实际应用中,Linux广泛用于服务器管理、软件开发、数据分析等领域,其强大的命令行工具如rsync、awk和sed能高效处理各类任务。本文特别针对新手常见问题,分享了VirtualBox配置优化、SSH连接保活、crontab环境变量等实用技巧,并深入探讨了/proc文件系统解析、性能调优参

weixin_30819085的博客 326

RK3588 实战级 YOLOv5 Android 全解析:NPU 量化 + 多线程 + 跟踪算法,源码一次买齐

本文将带你完成一个完整的AI视觉项目:在搭载RK3588芯片的Android开发板上运行实时目标检测与跟踪应用。实战目标:成功运行官方YOLOV5摄像头实时检测案例技术深度:深入理解RKNN开发框架和源码实现核心技能:掌握NPU推理、多线程并发、目标跟踪等关键技术。

FJN110的博客 157

华为OD机试2025A卷 - 用户调度问题(Java & Python& JS & C++ & C )

题目要求每个用户依次选择当前所能选择的最小资源消耗策略,并且若有多个策略的资源消耗相同,则选择最后一个策略。每个用户的选择是独立的,只考虑该用户的策略和相邻用户的约束,不考虑整个调度序列的全局资源消耗。每个用户根据自己的当前状态(即自己的三种选择的资源消耗)做出局部最优选择:在当前可选的策略中,选择消耗最小的那个。如果有多个最小值,则选择最后一个(根据题意)。这一选择是局部的最优,即在当下最有利的选择,但并不保证最终的整体系统资源消耗是最小的。

算法大师! 1万+

操作系统缓存机制深度解析:从页缓存到性能调优的隐形王者

在开发高性能应用时,我们常常第一时间想到 Redis 这类分布式缓存中间件,用它来扛住高并发、降低数据库压力。然而,你是否想过,在你按下键盘、点击鼠标,甚至代码中一个简单的 list.get(0) 背后,一个更底层、更强大、无处不在的“缓存系统”早已默默工作了数十年?它就是 操作系统 。本文将带你跳出应用层缓存的思维定式,深入操作系统内核,揭秘其作为“隐形缓存之王”的底层机制,理解为什么在特定场景下,优化操作系统缓存策略带来的性能提升,可能远超简单地堆砌 Redis 实例。 本文适合所有对系统性能优化、底层

weixin_34295316的博客 382

OpenClaw 运行时错误文档:Embedded Run Agent End with Stream Error(嵌入式运行代理结束流式错误)

OpenClaw运行时错误文档:EmbeddedRunAgentEndwithStreamError(OC-ERR-009) 该错误表示LLM提供商在流式传输过程中发生服务器端异常(HTTP 500),属于可恢复的中等严重性错误。典型表现为日志中出现包含"stream_error"和500状态码的错误信息。系统会自动进行错误分类(50%为服务过载,25%网络问题等),并通过内置机制尝试解决:包括模型切换、API密钥轮换和自动重试策略。用户可采取重试请求、切换模型或简化请求内容等操作,管理

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 554

【星海随笔】linux运维篇-精致小模块,小技巧。无他唯快尔

我会持续更新的。这个我可是买了华为云主机去测试的。多给点正向反馈。

weixin_41997073的博客 1071

`tokenizer.decode` 出现乱码或异常输出,怎么处理

摘要: 在使用Hugging Face Transformers库时,tokenizer.decode出现乱码或异常输出的解决方案包括:1)确保模型与分词器严格匹配,加载时使用trust_remote_code=True;2)谨慎处理特殊token,先保留所有token再针对性清理;3)校验模型输出token的维度和数值是否合法;4)通过convert_tokens_to_string替代解码;5)检查生成配置如max_new_tokens等参数。核心思路是确保模型与分词器逻辑对齐、输出token合法,必要

ZhangJiqun&191cm&85kg 585

2023华为OD机试真题B卷 Python 实现【最长的元音子串长度】

定义当一个字符串只有元音字母(a,e,i,o,u,A,E,I,O,U)组成,称为元音字符串,现给定一个字符串,请找出其中最长的元音字符串,并返回其长度,如果找不到请返回0, 字符串中任意一个连续字符组成的子序列称为该字符串的子串

MISAYAONE的博客 902
上一篇: Excel相关功能的正确使用
下一篇: ext4文件系统与日志相关的概念
SweeNeil
博客等级 码龄9年 251粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值