7D-AI系列:模型微调之mlx-lm

大模型的出现,导致信息量太大,只有静心动手操作,才能得到真理。

文章目录

    • 环境要求
    • 安装
    • 示例
    • mlx-lm微调工具参数
    • 准备数据集
    • 下载模型
    • 微调模型
    • 合并模型
    • 验证结果
      • 验证微调前的模型
      • 验证微调后的模型

环境要求

  • macbook pro m系列芯片
  • mlx环境已安装

安装

mlx-lm微调工具是一个用于微调基于mlx框架的预训练语言模型(LM)的工具。该工具提供了多种功能,包括预训练语言模型的微调、模型保存和加载、模型评估等功能。

(mlx) gaolou@GaodeMacBook-Pro mlx-examples % pip install mlx-lm

示例

当使用 generate 命令且不指定模型时,会自动下载 models--mlx-community--Llama-3.2-3B-Instruct-4bit 模型。并保在 /Users/gaolou/.cache/huggingface/hub 中。

(mlx) gaolou@GaodeMacBook-Pro mlx-examples % mlx_lm.generate --prompt "How tall is Mt Everest?"
special_tokens_map.json: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████| 296/296 [00:00<00:00, 2.87MB/s]
config.json: 1.12kB [00:00, 2.42MB/s]                                                                                                                             
tokenizer_config.json: 54.6kB [00:00, 66.4MB/s]                                                                                         | 1/6 [00:00<00:04,  1.04it/s]
model.safetensors.index.json: 45.7kB [00:00, 124MB/s]
tokenizer.json: 17.2MB [00:01, 16.9MB/s]
model.safetensors: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████| 1.81G/1.81G [00:47<00:00, 37.7MB/s]
Fetching 6 files: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6/6 [00:52<00:00,  8.78s/it]
==========
Mt. Everest is approximately 8,848 meters (29,029 feet) tall.
==========
Prompt: 41 tokens, 101.355 tokens-per-sec
Generation: 19 tokens, 120.663 tokens-per-sec
Peak memory: 1.937 GB
(mlx) gaolou@GaodeMacBook-Pro mlx-examples %

mlx-lm微调工具参数

(mlx) gaolou@GaodeMacBook-Pro mlx-lm % mlx_lm.lora --help                                  
usage: mlx_lm.lora [-h] [--model MODEL] [--train] [--data DATA] [--fine-tune-type {lora,dora,full}] [--optimizer {adam,adamw}] [--mask-prompt][--num-layers NUM_LAYERS] [--batch-size BATCH_SIZE] [--iters ITERS] [--val-batches VAL_BATCHES] [--learning-rate LEARNING_RATE][--steps-per-report STEPS_PER_REPORT] [--steps-per-eval STEPS_PER_EVAL] [--resume-adapter-file RESUME_ADAPTER_FILE] [--adapter-path ADAPTER_PATH][--save-every SAVE_EVERY] [--test] [--test-batches TEST_BATCHES] [--max-seq-length MAX_SEQ_LENGTH] [-c CONFIG] [--grad-checkpoint] [--seed SEED]
LoRA or QLoRA finetuning.
options:-h, --help            show this help message and exit--model MODEL         The path to the local model directory or Hugging Face repo.--train               Do training--data DATA           Directory with {train, valid, test}.jsonl files or the name of a Hugging Face dataset (e.g., 'mlx-community/wikisql')--fine-tune-type {lora,dora,full}Type of fine-tuning to perform: lora, dora, or full.--optimizer {adam,adamw}Optimizer to use for training: adam or adamw--mask-prompt         Mask the prompt in the loss when training--num-layers NUM_LAYERSNumber of layers to fine-tune. Default is 16, use -1 for all.--batch-size BATCH_SIZEMinibatch size.--iters ITERS         Iterations to train for.--val-batches VAL_BATCHESNumber of validation batches, -1 uses the entire validation set.--learning-rate LEARNING_RATEAdam learning rate.--steps-per-report STEPS_PER_REPORTNumber of training steps between loss reporting.--steps-per-eval STEPS_PER_EVALNumber of training steps between validations.--resume-adapter-file RESUME_ADAPTER_FILELoad path to resume training from the given fine-tuned weights.--adapter-path ADAPTER_PATHSave/load path for the fine-tuned weights.--save-every SAVE_EVERYSave the model every N iterations.--test                Evaluate on the test set after training--test-batches TEST_BATCHESNumber of test set batches, -1 uses the entire test set.--max-seq-length MAX_SEQ_LENGTHMaximum sequence length.-c CONFIG, --config CONFIGA YAML configuration file with the training options--grad-checkpoint     Use gradient checkpointing to reduce memory use.--seed SEED           The PRNG seed
(mlx) gaolou@GaodeMacBook-Pro mlx-lm % 

准备数据集

在用mlx_lm.lora 微调工具微调模型时,需要准备数据集。数据集可以是一个目录,包含 train.jsonl、valid.jsonl和test.jsonl文件,也可以是一个Hugging Face数据集。数据要超过5条。

示例如下:


{"prompt": "你是谁?","completion": "我是7DRESAR性能分析决策模型,我可以帮助你分析系统的性能问题,给出性能分析证据链,并提供相应的解决方案。"}
{"prompt": "如何分析操作系统中用户态CPU使用率高的根本原因?","completion": "根据7DRESAR性能分析决策树模型,分析us cpu使用率高根本原因的步骤如下:1. 首先要明确是us cpu使用率,而非其他cpu计数器。2. 然后查看us cpu消耗在哪个进程上。3, 再进一步根据进程号查看是哪一个线程消耗了us cpu。注意:如果不是某一个特定线程一直消耗us cpu,而是有多个线程消耗cpu,并且线程号在不断切换,则需要判断线程数设置是否合理。4. 当明确了某个线程消耗了us cpu之后,再多次打印线程栈,以确定正在执行的代码。5. 最后根据线程栈信息,确定是哪个代码片段消耗了us cpu。在java的应用中,可以用arthas之类的工具来跟踪方法的执行时间,其他的语言中也有类似的工具。"}
{"prompt": "如何分析操作系统中磁盘IO使用率高的根本原因?","completion": "根据7DRESAR性能分析决策树模型,分析磁盘IO使用率高的根本原因步骤如下:1. 首先要明确磁盘本身顺序、随机读写能力的上下限。也就是需要根据基准测试确定磁盘的最大读写能力。2. 然后查看磁盘IO消耗在哪个线程上。这一步在linux中可以直接通过iotop命令做到。3. 可以直接打线程栈,查看是哪一段代码在读写文件。4. 根据读写文件的逻辑,判断是否需要增加读写buffer的大小。5. 若读写文件不合理,则减少读写。"}
{"prompt": "如何分析操作系统中内存使用率高的根本原因?","completion": "根据7DRESAR性能分析决策树模型,分析内存率高的根本原因步骤如下:1. 对于java语言的应用,查看jvm的gc状态;对于其他语言开发的应用,则分析物理内存的使用情况。2. 若物理内存使用率高,在linux中可以使用top -Hp pid命令查看进程中哪个线程消耗了内存。3. 可以直接打线程栈,查看是哪一段代码在申请内存。4. 若申请内存不合理,则减少内存申请。5. 若内存申请合理,则需要考虑增加节点或内存。"}
{"prompt": "如何分析操作系统中网络是否阻塞?","completion": "根据7DRESAR性能分析决策树模型,分析网络是否阻塞步骤如下:1. 在linux中通过命令netstat查看recvq和sendq是否有积压。2. 若本机recvq有积压,则是阻塞在本机。3. 若是sendq有积压,则需要查看tcp连接的对端recvq是否也有积压,若有,则需要分析对端recvq积压的原因。"}
{"prompt": "如何分析操作系统中上下文切换是否合理?","completion": "根据7DRESAR性能分析决策树模型,分析上下文切换是否合理步骤如下:1. 在linux中通过命令vmstat查看上下文切换的次数。2. 若上下文切换次数高,则需要分析上下文切换的原因。3. 若上下文切换的原因是线程数设置不合理,则需要调整线程数。4. 若上下文切换的原因是线程切换的时间片不合理,则需要调整线程切换的时间片。"}

下载模型

你可以到网上下载一个模型权重。这里我之前在本地演示时,训练过的一个模型权重 Qwen2.5-0.5B-Instruct

注意:模型的选择要量力而为。

(mlx) gaolou@GaodeMacBook-Pro DeepSeek-R1-1.5B-7dresar % pwd
/Users/gaolou/Desktop/AI研究/AI模型权重/DeepSeek-R1-1.5B-7dresar
(mlx) gaolou@GaodeMacBook-Pro DeepSeek-R1-1.5B-7dresar % tree -h
[ 320]  .
├── [ 392]  Modelfile
├── [ 812]  config.json
├── [ 181]  generation_config.json
├── [3.3G]  model.safetensors
├── [ 485]  special_tokens_map.json
├── [ 11M]  tokenizer.json
├── [6.7K]  tokenizer_config.json
└── [ 16K]  读取模型文件.md
1 directory, 8 files

微调模型


(mlx) gaolou@GaodeMacBook-Pro mlx-lm % mlx_lm.lora --model /Users/gaolou/.cache/modelscope/hub/models/Qwen/Qwen2.5-0.5B-Instruct --train --data ./dataset
Loading pretrained model
Loading datasets
Training
Trainable parameters: 0.073% (0.360M/494.033M)
Starting training..., iters: 1000
Iter 1: Val loss 3.671, Val took 0.257s
Iter 10: Train loss 3.379, Learning Rate 1.000e-05, It/sec 3.233, Tokens/sec 2062.551, Trained Tokens 6380, Peak mem 3.130 GB
Iter 20: Train loss 2.893, Learning Rate 1.000e-05, It/sec 3.214, Tokens/sec 2050.724, Trained Tokens 12760, Peak mem 3.130 GB
Iter 30: Train loss 2.525, Learning Rate 1.000e-05, It/sec 3.227, Tokens/sec 2058.875, Trained Tokens 19140, Peak mem 3.130 GB
Iter 40: Train loss 2.198, Learning Rate 1.000e-05, It/sec 3.271, Tokens/sec 2086.831, Trained Tokens 25520, Peak mem 3.130 GB
----------删除了部分输出日志------------
Iter 990: Train loss 0.009, Learning Rate 1.000e-05, It/sec 3.205, Tokens/sec 2044.611, Trained Tokens 631620, Peak mem 3.136 GB
Iter 1000: Val loss 0.009, Val took 0.162s
Iter 1000: Train loss 0.009, Learning Rate 1.000e-05, It/sec 3.209, Tokens/sec 2047.448, Trained Tokens 638000, Peak mem 3.136 GB
Iter 1000: Saved adapter weights to adapters/adapters.safetensors and adapters/0001000_adapters.safetensors.
Saved final weights to adapters/adapters.safetensors.
(mlx) gaolou@GaodeMacBook-Pro mlx-lm % 

合并模型

(mlx) gaolou@GaodeMacBook-Pro mlx-lm % mlx_lm.fuse --model /Users/gaolou/.cache/modelscope/hub/models/Qwen/Qwen2.5-0.5B-Instruct --adapter-path ./adapters --save-path Qwen2.5-0.5B-7dresar-v0.1
Loading pretrained model
(mlx) gaolou@GaodeMacBook-Pro mlx-lm % ll
total 88
drwxrwxr-x@ 14 gaolou  staff   448  4 12 03:39 tests
-rw-rw-r--@  1 gaolou  staff  1509  4 12 03:39 setup.py
-rw-rw-r--@  1 gaolou  staff    77  4 12 03:39 requirements.txt
drwxrwxr-x@ 29 gaolou  staff   928  4 12 03:39 mlx_lm
-rw-rw-r--@  1 gaolou  staff  9186  4 12 03:39 README.md
-rw-rw-r--@  1 gaolou  staff    56  4 12 03:39 MANIFEST.in
-rw-rw-r--@  1 gaolou  staff  1066  4 12 03:39 LICENSE
-rw-rw-r--@  1 gaolou  staff  2773  4 12 03:39 CONTRIBUTING.md
-rw-rw-r--@  1 gaolou  staff  5544  4 12 03:39 CODE_OF_CONDUCT.md
-rw-rw-r--@  1 gaolou  staff   640  4 12 03:39 ACKNOWLEDGMENTS.md
drwxr-xr-x@  5 gaolou  staff   160  4 12 16:27 dataset
drwxr-xr-x@ 14 gaolou  staff   448  4 12 16:57 adapters
drwxr-xr-x@  8 gaolou  staff   256  4 12 17:03 DeepSeek-R1-1.5B-7dresar-v0.1
drwxr-xr-x@ 12 gaolou  staff   384  4 12 18:35 DeepSeek-R1-8B-7dresar-v0.1
drwxr-xr-x@ 11 gaolou  staff   352  4 12 19:11 Qwen2.5-0.5B-7dresar-v0.1
(mlx) gaolou@GaodeMacBook-Pro mlx-lm % tree -h Qwen2.5-0.5B-7dresar-v0.1
[ 352]  Qwen2.5-0.5B-7dresar-v0.1
├── [ 605]  added_tokens.json
├── [ 710]  config.json
├── [1.6M]  merges.txt
├── [942M]  model.safetensors
├── [ 20K]  model.safetensors.index.json
├── [ 613]  special_tokens_map.json
├── [ 11M]  tokenizer.json
├── [7.2K]  tokenizer_config.json
└── [2.6M]  vocab.json
1 directory, 9 files
(mlx) gaolou@GaodeMacBook-Pro mlx-lm % 

验证结果

验证微调前的模型


(mlx) gaolou@GaodeMacBook-Pro mlx-lm % mlx_lm.generate --model /Users/gaolou/.cache/modelscope/hub/models/Qwen/Qwen2.5-0.5B-Instruct --max-tokens 1000 --prompt "如何分析操作系统中用户态CPU使用率高的根本原因?"
==========
分析操作系统中用户态CPU使用率高的根本原因,通常需要从以下几个方面进行深入分析:
1. **系统资源使用情况**:首先,需要了解系统的总资源使用情况,包括CPU、内存、磁盘I/O等。如果系统资源使用率过高,可能意味着系统负载过高,需要进一步分析。
2. **进程和线程管理**:检查进程和线程的使用情况。如果某些进程或线程占用大量CPU资源,可能是由于它们的运行状态不稳定或资源分配不当导致的。
3. **内存使用情况**:检查内存使用情况,包括内存的分配和释放。如果内存分配过多或释放不足,可能会导致CPU使用率过高。
4. **磁盘I/O使用情况**:检查磁盘I/O使用情况,包括磁盘的读写速度和磁盘I/O的总请求量。如果磁盘I/O使用率过高,可能是由于磁盘的性能问题或磁盘I/O的调度策略不当导致的。
5. **系统调度和资源管理**:检查系统调度和资源管理的策略,包括进程调度、内存分配和磁盘I/O调度等。如果这些策略不当,可能会导致CPU使用率过高。
6. **系统优化和调整**:根据上述分析,可以考虑对系统进行优化和调整,例如调整进程和线程的调度策略、优化磁盘I/O调度策略、调整内存分配策略等。
7. **系统监控和日志分析**:通过系统监控和日志分析,可以更深入地了解CPU使用率高的原因,包括异常的CPU使用情况、异常的内存使用情况、异常的磁盘I/O使用情况等。
8. **性能测试和优化**:进行性能测试和优化,找出性能瓶颈,然后针对性地进行优化。
通过上述分析和优化,可以有效地解决用户态CPU使用率高的问题,提高系统的性能和稳定性。
==========
Prompt: 42 tokens, 1476.203 tokens-per-sec
Generation: 404 tokens, 194.790 tokens-per-sec
Peak memory: 1.044 GB

验证微调后的模型

(mlx) gaolou@GaodeMacBook-Pro mlx-lm % mlx_lm.generate --model /Users/gaolou/Desktop/AI研究/AI工具集/mlx/mlx-lm/Qwen2.5-0.5B-7dresar-v0.1 --max-tokens 1000 --prompt "如何分析操作系统中用户态CPU使用率高的 根本原因?"
==========
根据7DRESAR性能分析决策树模型,分析us cpu使用率高根本原因的步骤如下:
1. 首先要明确是us cpu使用率,而非其他cpu计数器。
2. 然后查看us cpu消耗在哪个进程上。
3, 再进一步根据进程号查看是哪一个线程消耗了us cpu。注意:如果不是某一个特定线程一直消耗us cpu,而是有多个线程消耗cpu,并且线程号在不断切换,则需要判断线程数设置是否合理。
4. 当明确了某个线程消耗了us cpu之后,再多次打印线程栈,以确定正在执行的代码。
5. 最后根据线程栈信息,确定是哪个代码片段消耗了us cpu。在java的应用中,可以用arthas之类的工具来跟踪方法的执行时间,其他的语言中也有类似的工具。
==========
Prompt: 42 tokens, 1410.335 tokens-per-sec
Generation: 187 tokens, 196.516 tokens-per-sec
Peak memory: 1.044 GB

以上输出,格式有整理,其他没修改。

最后,你想看哪些和AI大模型相关的技术点?可以留言,我们一一拆解。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker —— 隔离的基本操作(1)

Docker —— 隔离的基本操作&#xff08;1&#xff09; 1. 用户和权限隔离2. 进程隔离3. 文件系统隔离4. 资源隔离&#xff08;Cgroups&#xff09;5. 网络隔离6. 安全增强&#xff08;SELinux/AppArmor&#xff09;7. 容器技术&#xff08;Docker/LXC&#xff09;总结 dd基本语…

PWN基础-ROP技术-ret2syscall突破NX保护

ROP&#xff08;Return-Oriented Programming&#xff0c;返回导向编程&#xff09;是一种利用程序已有代码片段来执行任意指令的攻击技术&#xff0c;常用于绕过现代系统的安全机制&#xff0c;尤其是不可执行栈&#xff08;NX&#xff09;。 常规检查一下&#xff1a; 32 位…

关于 js:2. 对象与原型链

一、对象 对象是&#xff1a; 键值对集合 所有非原始类型&#xff08;number、string、boolean、null、undefined、symbol、bigint&#xff09;都是对象 支持动态增删属性 每个对象都继承自 Object.prototype&#xff0c;具备原型链结构 1. 对象的创建方式 字面量方式&a…

AtCoder 第404场初级竞赛 A~E题解

A Not Found 【题目链接】 原题链接:A - Not Found 【考点】 枚举,数组计数法 【题目大意】 找到在26个字母中,未输出的一个字母,如果有多个,输出其中一个即可。 【解析】 遍历字符串,使用数组的记录对应字母的出现次数,最后遍历数组为0的下标,输出对应的字母即…

检测内存条好坏有工具,推荐几款内存检测工具

检测内存条的好坏其实很重要&#xff0c;这直接就关系到计算机是不是能够稳定的运行&#xff0c;也有一部分人就会关注内存检测的工具。你应该如何来选择的&#xff0c;不如看一下以下的这几个。 MemTest86是一个比较受到大家喜欢的内存检测工具&#xff0c;会支持各种类型&…

01Introduction

文本主题 关于协作式多智能体强化学习的简介 文章目录 文本主题一、MARL主要框架集中式训练与执行 (CTE)集中式训练分布式执行&#xff08;CTDE&#xff09;分布式训练与执行&#xff08;DTE&#xff09; 二、Dec-POMDPjoint policy V and Q 一、MARL主要框架 MARL当前主流的…

小程序问题(记录版)

1、样式不生效 在h5上生效 但是 小程序上没反应 解决办法&#xff1a;解除组件样式隔离 1、isolated 表示启用样式隔离&#xff0c;在自定义组件内外&#xff0c;使用 class 指定的样式将不会相互影响&#xff08;一般情况下的默认值&#xff09; 2、apply-shared 表示页面 wxs…

排列组合算法:解锁数据世界的魔法钥匙

在 C 算法的奇幻世界里&#xff0c;排列和组合算法就像是两把神奇的魔法钥匙&#xff0c;能够帮我们解锁数据世界中各种复杂问题的大门。今天&#xff0c;作为 C 算法小白的我&#xff0c;就带大家一起走进排列和组合算法的奇妙天地。 排列算法&#xff1a;创造所有可能的顺序…

深入探讨 UDP 协议与多线程 HTTP 服务器

深入探讨 UDP 协议与多线程 HTTP 服务器 一、UDP 协议&#xff1a;高效但“不羁”的传输使者 UDP 协议以其独特的特性在网络传输中占据一席之地&#xff0c;适用于对实时性要求高、能容忍少量数据丢失的场景。 1. UDP 的特点解析 无连接&#xff1a;无需提前建立连接&…

引用第三方自定义组件——微信小程序学习笔记

1. 使用 npm 安装第三方包 1.1 下载安装Node.js 工具 下载地址&#xff1a;Node.js — Download Node.js 1.2 安装 npm 包 在项目空白处右键弹出菜单&#xff0c;选择“在外部终端窗口打开”&#xff0c;打开命令行工具&#xff0c;输入以下指令&#xff1a; 1> 初始化:…

数字化转型是往哪转?怎么转?

写在前面 当下数字化转型的风还在吹&#xff0c;企业数字化转型过程中以数字化项目满足业务化需求&#xff0c;已有相关数字化平台的话&#xff0c;就搞大平台、大系统&#xff0c;解决数据孤岛。政府数字化转型亦是如此&#xff0c;某些省市发了系统优化整合的文&#xff0c;旨…

嵌入式学习--江协51单片机day2

今天学的不多&#xff0c;内容为&#xff1a;静态、动态数码管的控制&#xff0c;模块化编程和lcd1602调试工具 数码管的控制 由于内部电路的设计&#xff0c;数码管每次只能显示一个位置的一个数字&#xff0c;动态的实现是基于不同位置的闪烁频率高。 P2_4,P2_3,P2_2控制位…

《数据结构:二叉搜索树(Binary Search Tree)》

文章目录 :red_circle:一、二叉搜索树的概念:red_circle:二、二叉搜索树的性能分析:red_circle:三、二叉搜索树的操作&#xff08;一&#xff09;插入&#xff08;二&#xff09;查找&#xff08;三&#xff09;删除 :red_circle:四、二叉搜索树的实现代码&#xff08;一&#…

【Linux相关】实时查看Nvidia-smi使用情况

【Linux相关】 实时查看Nvidia-smi使用情况 文章目录 实时查看Nvidia-smi使用情况 实时查看Nvidia-smi使用情况 在本地终端执行下述语句 watch -n 1 nvidia-smi每一秒都会更新&#xff0c;将 1 改为其他数字可以满足不同需求

Kotlin密封类优化Android状态管理

Kotlin 的密封类&#xff08;Sealed Class&#xff09;确实是 Android 开发中管理复杂 UI 状态的利器。它通过类型安全的层次结构&#xff0c;让状态管理代码更加清晰简洁。让我们从实际开发场景出发&#xff0c;深入探讨其应用&#xff1a; 一、密封类核心优势 受限的类继承…

JavaWeb:SpringBootWeb快速入门

介绍 Spring SpringBoot 入门程序 需求 步骤 修改端口 1.新建application.yml #设置端口 server:port: 8081入门程序-分析 为什么main方法能启动web应用-内嵌tomcat 为什么tomcat能定位HelloController程序 请求先到DisPatcherServlet&#xff0c;根据路径转发 小结 1.…

Unity学习笔记二

文章目录 3D数学公共计算结构体Mathf常用成员三角函数 向量Vector3基本成员点乘叉乘插值运算 四元数引出基本概念Quaternion结构体成员四元数运算 更多的Mono延迟函数协同程序多线程相关协程概念辨析协程本体协程调度器 Resources资源动态加载特殊文件夹Resources同步加载Resou…

为什么Transformer推理需要做KV缓存

一、我们先来回忆一下在transformer中KV在哪里出现过&#xff0c;都有什么作用&#xff1f; α的计算过程&#xff1a; 这里引入三个向量&#xff1a; 图中的q为Query&#xff0c;用来匹配key值 图中的k为key,用来被Query匹配 图中的Value&#xff0c;是用来被进行加权平均的 由…

【大模型面试】大模型(LLMs)高频面题全面整理(★2025年5月最新版★)

【大模型面试】大模型&#xff08;LLMs&#xff09;高频面题全面整理&#xff08;★2025年5月最新版★&#xff09; &#x1f31f; 嗨&#xff0c;你好&#xff0c;我是 青松 &#xff01; &#x1f308; 自小刺头深草里&#xff0c;而今渐觉出蓬蒿。 本笔记适合大模型初学者和…

JAVA:使用 iTextPDF 处理 PDF 的技术详解

1、简述 iTextPDF 是一个功能强大的 Java PDF 库,可以用来创建、修改和处理 PDF 文档。通过它,我们可以完成如生成 PDF、读取 PDF 内容、添加水印、合并 PDF 等多种操作。本篇博客将详细介绍 iTextPDF 的使用方法,并提供一些实践样例,帮助开发者快速上手。 样例代码: htt…