在 Mac 上进行本地 LLM 微调(M1 16GB)

news2024/12/23 14:40:27

适合初学者的 Python 代码演练 (ft. MLX)

         欢迎来到雲闪世界。本文展示了如何使用 Google Colab 上的单个(免费)GPU 微调 LLM。虽然该示例(以及许多其他示例)可以在 Nvidia 硬件上轻松运行,但它们并不容易适应 M 系列 Mac。介绍一种在 Mac 上本地微调 LLM 的简单方法。

          随着开源大型语言模型 (LLM) 和高效微调方法的兴起,构建自定义 ML 解决方案从未如此简单。现在,任何拥有单个 GPU 的人都可以在本地机器上微调 LLM

然而,由于苹果的 M 系列芯片,Mac 用户在很大程度上被排除在这一趋势之外。这些芯片采用统一的内存框架,无需 GPU。因此,许多用于运行和训练 LLM 的(以 GPU 为中心的)开源工具与现代 Mac 计算能力不兼容(或没有充分利用)。

在发现 MLX Python 库之前,我几乎放弃了在本地培养法学硕士的梦想。

美拉尼西亚

MLX是 Apple 机器学习研究团队开发的 Python 库,用于在 Apple 芯片上高效运行矩阵运算。这很重要,因为矩阵运算是神经网络底层的核心计算。

MLX 的主要优势在于它充分利用了 M 系列芯片的统一内存范式,这使得中等系统(如我的 M1 16GB)能够在大型模型(例如 Mistral 7b Instruct)上运行微调作业。

虽然该库没有用于训练 Hugging Face 等模型的高级抽象,但有一个LoRA 的示例实现,可以轻松破解并适应其他用例。

这正是我在下面的例子中所做的。

示例代码:微调 Mistral 7b 指令

         我不会使用 Hugging Face 的 Transformers 库和 Google Colab,而是使用 MLX 库和我的本地机器(2020 Mac Mini M1 16GB)。

与前面的示例类似,我将对Mistral-7b-Instruct 的量化版本进行微调,以按照我的喜好回应 YouTube 评论。我使用 QLoRA 参数高效微调方法。如果您不熟悉 QLoRA,我在此处对该方法进行了概述。

1)设置环境

在运行示例代码之前,我们需要设置 Python 环境。第一步是从GitHub repo下载代码。

git克隆https://github.com/ShawhinT/YouTube-Blog.git

本示例的代码位于LLMs/qlora-mlx子目录中。我们可以导航到此文件夹并创建一个新的 Python 环境(这里,我将其称为mlx-env)。

# change dir
cd LLMs/qlora-mlx

# create py venv
python -m venv mlx-env

接下来,我们激活环境并从 requirements.txt 文件中安装要求。注意:mlx 要求您的系统具有 M 系列芯片、Python >= 3.8 和 macOS >= 13.5

# activate venv
source mlx-env/bin/activate

# install requirements
pip install -r requirements.txt

2)使用未微调模型进行推理

现在我们已经安装了mlx和其他依赖项,让我们运行一些 Python 代码!我们首先导入有用的库。

# import modules (this is Python code now)
import subprocess
from mlx_lm import load, generate

我们将使用子进程模块通过 Python 运行终端命令,并使用mlx-lm库在我们预先训练的模型上运行推理。

mlx-lm建立在mlx之上,专门用于运行来自 Hugging Face hub 的模型。下面介绍如何使用它从现有模型生成文本。

# define inputs
model_path = "mlx-community/Mistral-7B-Instruct-v0.2-4bit"
prompt = prompt_builder("Great content, thank you!")
max_tokens = 140

# load model
model, tokenizer = load(model_path)

# generate response
response = generate(model, tokenizer, prompt=prompt, 
                                      max_tokens = max_tokens, 
                                      verbose=True)

注意:Hugging Face mlx-community 页面上的数百种模型中的任何一种都可以轻松用于推理。如果您想使用不可用的模型(不太可能),您可以使用scripts/convert.py脚本将其转换为兼容格式。

prompt_builder ()函数接受 YouTube 评论并将其集成到提示模板中,如下所示。

# prompt format
intstructions_string = f"""ShawGPT, functioning as a virtual data science \
consultant on YouTube, communicates in clear, accessible language, escalating \
to technical depth upon request. \
It reacts to feedback aptly and ends responses with its signature '–ShawGPT'. \
ShawGPT will tailor the length of its responses to match the viewer's comment, \
providing concise acknowledgments to brief expressions of gratitude or \
feedback, thus keeping the interaction natural and engaging.

Please respond to the following comment.
"""

# define lambda function
prompt_builder = lambda comment: f'''<s>[INST] {intstructions_string} \n{comment} \n[/INST]\n'''

以下是模型在未经微调的情况下对评论“很棒的内容,谢谢! ”的回应。

–ShawGPT: Thank you for your kind words! I'm glad you found the content helpful
and enjoyable. If you have any specific questions or topics you'd like me to 
cover in more detail, feel free to ask!

虽然回复是连贯的,但主要存在两个问题。1)签名“-ShawGPT”放在回复的前面而不是结尾(按照指示),2)回复比我实际回复这样的评论的方式要长得多。

3)准备训练数据

在运行微调作业之前,我们必须准备训练、测试和验证数据集。在这里,我使用来自我的 YouTube 频道的 50 条真实评论和回复进行训练,使用 10 条评论/回复进行验证和测试(总共 70 个示例)。

下面给出了一个训练示例。它采用 JSON 格式,即键值对,其中键 = “文本”,值 = 合并的提示、评论和响应。

{"text": "<s>[INST] ShawGPT, functioning as a virtual data science consultant 
on YouTube, communicates in clear, accessible language, escalating to technical
 depth upon request. It reacts to feedback aptly and ends responses with its 
signature '\u2013ShawGPT'. ShawGPT will tailor the length of its responses to 
match the viewer's comment, providing concise acknowledgments to brief 
expressions of gratitude or feedback, thus keeping the interaction natural and 
engaging.\n\nPlease respond to the following comment.\n \nThis was a very 
thorough introduction to LLMs and answered many questions I had. Thank you. 
\n[/INST]\nGreat to hear, glad it was helpful :) -ShawGPT</s>"}

从 .csv 文件生成训练、测试和验证数据集的代码可在GitHub上找到。

4)微调模型

准备好训练数据后,我们可以微调模型。在这里,我使用mlx团队创建的lora.py示例脚本。

该脚本保存在我们克隆的 repo 的scripts 文件夹中,train/test/val 数据保存在data文件夹中。要运行微调作业,我们可以运行以下终端命令。

python scripts/lora.py --model mlx-community/Mistral-7B-Instruct-v0.2-4bit \
                       --train \
                       --iters 100 \
                       --steps-per-eval 10 \
                       --val-batches -1 \
                       --learning-rate 1e-5 \
                       --lora-layers 16 \
                       --test

# --train = runs LoRA training
# --iters = number of training steps
# --steps-per-eval = number steps to do before computing val loss
# --val-batches = number val dataset examples to use in val loss (-1 = all)
# --learning-rate (same as default)
# --lora-layers (same as default)
# --test = computes test loss at the end of training

为了尽快完成训练,我关闭了机器上的所有其他进程,以便为微调过程分配尽可能多的内存。在我的 M1 上,内存为 16GB,运行大约需要15-20 分钟,峰值内存约为 13-14GB

注意:我必须对lora.py 脚本的第 340-341 行进行一处更改以避免过度拟合,即将 LoRA 适配器的等级从 r=8 更改为 r=4。

5)使用微调模型进行推理

训练完成后,工作目录中会出现一个名为adapters.npz的文件。其中包含 LoRA 适配器权重。

要使用这些脚本进行推理,我们可以再次使用 lora.py。不过,这一次,我没有直接从终端运行脚本,而是使用subprocess模块在 Python 中运行脚本。这使我能够使用之前定义的prompt_builder()函数。

# define inputs
adapter_path = "adapters.npz" # same as default
max_tokens_str = "140" # must be string

# define command
command = ['python', 'scripts/lora.py', '--model', model_path, 
                                        '--adapter-file', adapter_path, 
                                        '--max-tokens', max_tokens_str, 
                                        '--prompt', prompt]

# run command and print results continuously
run_command_with_live_output(command)

run_command_with_live_output ()是一个辅助函数(由 ChatGPT 提供),它不断打印来自终端命令的进程输出。这样就避免了必须等到推理完成后才能看到任何输出。

def run_command_with_live_output(command: list[str]) -> None:
    """
    Courtesy of ChatGPT:
    Runs a command and prints its output line by line as it executes.

    Args:
        command (List[str]): The command and its arguments to be executed.

    Returns:
        None
    """
    process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

    # Print the output line by line
    while True:
        output = process.stdout.readline()
        if output == '' and process.poll() is not None:
            break
        if output:
            print(output.strip())
        
    # Print the error output, if any
    err_output = process.stderr.read()
    if err_output:
        print(err_output)

以下是模型对同一条评论(很棒的内容,谢谢!)的回应,但现在已经经过了微调

Glad you enjoyed it! -ShawGPT

这个响应比微调之前好多了。“-ShawGPT”签名在正确的位置,听起来就像我实际上会说的话。

但这个评论很容易回应。让我们看看一些更具挑战性的东西,比如下面的这个。

Comment: 
I discovered your channel yesterday and I am hucked, great job. 
It would be nice to see a video of fine tuning ShawGPT using HF, I saw a video 
you did running on Colab using Mistal-7b, any chance to do a video using your 
laptop (Mac) or using HF spaces?
Response:
Thanks, glad you enjoyed it! I'm looking forward to doing a fine tuning video 
on my laptop. I've got an M1 Mac Mini that runs the latest versions of the HF 
API. -ShawGPT

乍一看,这是一个很棒的响应。该模型响应恰当,并进行了适当的签名。它还幸运地说我有一台 M1 Mac Mini 😉

但是,这有两个问题。首先,Mac Mini 是台式机,不是笔记本电脑。其次,该示例不直接使用 HF API。

感谢关注雲闪世界。(亚马逊aws和谷歌GCP服务协助解决云计算及产业相关解决方案)

 订阅频道(https://t.me/awsgoogvps_Host)
 TG交流群(t.me/awsgoogvpsHost)

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

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

相关文章

Windows10点击文件夹右键卡死的解决办法

1、首先同时按下【WinR】打开运行页面&#xff0c;输入命令【regedit】按下回车或者点击确定。 2、打开注册表编辑器后&#xff0c;定位到如下位置“HKEY_CLASSES_ROOT\Directory\Background\Shellex\ContextMenuHandlers”。 3、然后在其中将所有名为“New”的文件或项全部删…

边缘计算平台模型-Gemma 2

我们生活在一个充满科技创新的时代&#xff0c;这已经成为我几乎每天都会重复的话题。这一次&#xff0c;我们带来了一个重磅消息&#xff1a;Google刚刚发布了Gemma 2&#xff0c;这是一款拥有22亿参数的指令调优模型。这意味着它已经在指令及其响应上进行了训练或微调。Gemma…

Navicat 数据传输详解(将源数据库的多个表结构与数据复制到目标数据库)

Navicat 数据传输详解&#xff08;将源数据库的多个表结构与数据复制到目标数据库&#xff09; 1.打开Navicat &#xff0c;先连接源数据库和目标数据库。2.点击工具选项卡&#xff0c;选择数据传输3.左边是源数据库&#xff0c;右边是目标数据库。4.选择要同步的表。5.开始同步…

为什么很多人都无法解决 VSCode C 系列调试问题 (经验分享 有用)

目录 个人失败案例 断点打了 (也没用) lagunch配置了 (也没用) 插件安装了 (也没用) 无中文路径 (也没用) ​编辑 失败案例分析✨ llvm-mingw 编译器为例 main.cpp launch.json 个人失败案例 你们都很棒 很优秀 &#xff0c;环境方面也正常&#xff0c;但为什么还是…

【海外高校联合支持举办 | 学术大咖fellow汇聚】2024年人工智能与数字化管理国际会议(ICAIDM 2024,9月20-22)

2024年人工智能与数字化管理国际会议将于2024年9月22-24日在中国江苏省南京市隆重召开。 在快速发展的数字时代&#xff0c;人工智能已成为驱动创新、优化运营和塑造未来的关键技术。随着人工智能技术的日益成熟及其在各行各业的深入应用&#xff0c;如何有效地进行数字化管理…

Elasticsearch大数据搜索引擎(经典版)(电子版教程)

前言 在信息时代&#xff0c;可供获取的数据加速涌现&#xff0c;我们可以通过搜索引警来挖掘大数据的价值&#xff0c;百度就是一个大的数据搜索引擎。Lucene 是一个 Java 语言开发的开源全文检索引擎工具包。Lucene 穿了一件json 的外衣&#xff0c;就是 Elasticsearch。Ela…

平衡三进制存算一体架构

PS:天天水一贴&#xff0c;快乐又舒心。。。 1、存算一体概念 最近想搞平衡三进制的虚拟机&#xff0c;但是写来写去都感觉不对味&#xff0c;能用是能用&#xff0c;但写起来感觉就是很奇怪&#xff0c;用了二种编码&#xff0c;想来想去是不够原生三进制的编写&#xff0c;有…

企业差旅支出“降本增效”CFO避坑指南之三—— 仅凭一单,更换差旅供应商?

在企业运营过程中&#xff0c;差旅支出是CFO们需要精细管理的重要成本项。然而&#xff0c;许多中小企业在商旅供应商的选择上&#xff0c;往往容易陷入“仅凭一单价格高&#xff0c;即更换差旅供应商”的误区。这种做法忽视了商旅市场的复杂性和多样性&#xff0c;可能导致企业…

通过 Python脚本,实现字体文件otf,ttf文件大小的减少

FontTools 是一个用于操作字体文件的 Python 库。它支持多种字体格式&#xff0c;包括 TrueType (TTF) 和 OpenType (OTF)&#xff0c;并提供功能来编辑、合并、子集化和生成字体文件 前提&#xff1a;安装了 Python 1、安装 fonttools 库 pip3 install fonttools2、编写脚本…

Qt项目——文本编辑器(功能模块④)

项目地址&#xff1a;GitHub - Outlier9/CatEditor: Cat文本编辑器--Qt 有帮助的话各位点点 star 啦&#xff0c;感谢&#xff01; 如果有需要学习该项目的人&#xff0c;觉得看文档较为困难&#xff0c;可以加我联系方式&#xff0c;给github点个star后可免费提供学习视频&…

颠覆虚拟试衣行业标准!阿里发布OutfitAnyone:任意服装+任意人!

文章链接&#xff1a;https://arxiv.org/pdf/2407.16224 git链接:https://humanaigc.github.io/outfit-anyone/ huggingface: https://huggingface.co/spaces/HumanAIGC/OutfitAnyone 亮点直击 顶尖逼真度&#xff1a;OutfitAnyone 方法为虚拟试穿设立了新的行业标准&#xff0…

【Redis 进阶】持久化(RDB AOF)

Redis&#xff08;数据存储在内存中&#xff09;支持 RDB 和 AOF 两种持久化&#xff08;和 MySQL 里的持久性是一回事&#xff0c;把数据存储在硬盘上&#xff0c;重启进程 / 主机后数据仍然存在 —— 持久&#xff1b;把数据存储在内存上&#xff0c;重启进程 / 主机后数据消…

夏日清凉体验:气膜体育馆的运动之乐—轻空间

夏季的酷热常常让人们望而却步&#xff0c;尤其是对于热爱运动的人来说&#xff0c;寻找一个凉爽舒适的运动场所显得尤为重要。气膜体育馆因其独特的建筑特点和环境控制系统&#xff0c;成为了炎炎夏日里篮球、羽毛球等运动项目的理想场地。轻空间将探讨在气膜体育馆内运动的独…

活动报道 | 盘古信息携IMS OS+小快轻准产品集亮相东莞市中小数转试点供需对接会

8月1日&#xff0c;由东莞市工业和信息化局主办&#xff0c;南城街道经济发展局承办&#xff0c;东莞市软件行业协会协办的东莞市中小企业数字化转型城市试点供需对接会&#xff08;城区和水乡新城片区&#xff09;隆重召开。市工业和信息化局副局长江小敏、市工业和信息化局信…

揭秘 CPU 是如何执行计算机指令的

1 CPU 内部逻辑结构 之前的文章《揭秘代码是如何变成机器码的》&#xff0c;其中说到&#xff0c;如果从软件的角度来讲&#xff0c;CPU 就是一个执行各种计算机指令&#xff08;Instruction Code&#xff09;的逻辑机器。 那么这个逻辑机器内部是什么样的&#xff1f;又是如…

寥寥数笔,动画自成!阿里Tora: 首个轨迹引导的DiT创新实现精确运动控制视频生成

论文链接&#xff1a;https://arxiv.org/pdf/2407.21705 项目链接&#xff1a;https://ali-videoai.github.io/tora_video/ 亮点直击 本文引入了Tora&#xff0c;这是第一个轨迹导向的DiT用于视频生成。如下图2所示&#xff0c;Tora无缝整合了广泛的视觉和轨迹指令&#xff0c;…

数据挖掘实战-基于Prophet时间序列模型预测阿里巴巴股票价格趋势(文末送书)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

【系统架构设计师】二十三、通信系统架构设计理论与实践①

目录 一、通信系统网络架构 1.1 局域网网络架构 1.1.1 单核心架构 1.1.2 双核心架构 1.1.3 环型架构 1.1.4 层次型架构 1.2 广域网网络架构 1.2.1 单核心广域网 1.2.2 双核心广域网 1.2.3 环型广域网 1.2.4 半冗余广域网 1.2.5 对等子域广域网 1.2.6 层次子域架构…

文献阅读:基于拓扑结构模型构建ICI收益诊断模型

介绍 Custom scoring based on ecological topology of gut microbiota associated with cancer immunotherapy outcome是来自法国Gustave Roussy Cancer Campus的Laurence Zitvogel实验室最近发表在cell的关于使用肠道微生物拓扑结构预测免疫治疗疗效的文章。 该研究提供基于…

html+css 实现左平移背景按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…