今天这篇博客转载自我们的全栈工程师朱唯唯。在使用 Ollma 进行大模型加载时,她尝试使用了 JuiceFS 进行模型共享,JuiceFS 的数据预热和分布式缓存功能显著提升了加载效率,优化了性能瓶颈问题。

01 背景

随着 AI 技术的发展,大模型已经潜移默化地影响着我们的生活。商业 LLM 始终因为收费、黑盒、数据安全等原因,跟用户之间仿佛隔着一道天堑。越来越多的大模型选择了开源,让用户能够更加方便且放心的去使用自己的大模型。

Ollma 是一个简化大模型部署和运行的工具,一方面通过提供类 Docker 的使用方式,运行一个大模型实例就和启动一个容器一样简单,另一方面,通过提供 OpenAI 兼容的 API,磨平大模型之间的使用差异。

为了避免使用 “人工智障”,我们会选择尽量大规模参数的模型,但众所周知,模型参数越大,虽然拥有更出色的表现。但也具有更大的体积,比如 Llama 3.1 70B 模型大小为 40GB。

在当下,一个和业务功能强相关的大文件管理是一件很头疼的事情。一般无非两个方案,一个是模型制品化,另一个是共享存储。

  • 模型制品化:将大模型本身打入制品交付物中,无论是 Docker 镜像还是 OS 快照,力求通过 IaaS 或者 PaaS 的能力完成大模型的版本管理和分发;
  • 共享存储:共享存储的思路就比较简单,直接将大模型放在一个共享文件系统中,按需拉取。

模型制品化更像是热启动,通过复用平台层制品分发的能力,在实例就绪时,大模型就已经在本地了,但其瓶颈在于大文件的分发,软件工程发展到现在的阶段,大制品的分发手段依然有限。

共享存储更像冷启动,在实例启动时,虽然可以看到远端的模型文件,但需要远端加载运行。虽然共享存储是一个很符合直觉的方式,但十分考验共享存储,搞不好共享存储本身就是整个加载阶段的瓶颈。

但是,如果一个共享存储本身也支持数据预热、分布式缓存等热启动手段,那情况就另说了,而 JuiceFS 就是这么一个项目

本文将通过一个 Demo,介绍 JuiceFS 共享存储的部分,基于 JuiceFS 提供的分布式文件系统的能力,使得 Ollama 模型文件,一次拉取,到处运行。

02 一次拉取

本文以 Linux 机器为例,演示如何拉取模型。

准备 JuiceFS 文件系统

Ollama 默认会将模型数据放在 /root/.ollama 下,所以这里将 JuiceFS 挂载在 /root/.ollama 下:

$ juicefs mount weiwei /root/.ollama --subdir=ollama

这样 Ollama 拉取的模型数据就会放在 JuiceFS 的文件系统中了。

拉取模型安装

Ollama:

curl -fsSL https://ollama.com/install.sh | sh

拉取模型,这里以 llama 3.1 8B 举例:

$ ollama pull llama3.1
pulling manifest
pulling 8eeb52dfb3bb... 100% ▕█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ 4.7 GB
pulling 11ce4ee3e170... 100% ▕█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏ 1.7 KB
pulling 0ba8f0e314b4... 100% ▕█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏  12 KB
pulling 56bb8bd477a5... 100% ▕█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏   96 B
pulling 1a4c3c319823... 100% ▕█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████▏  485 B
verifying sha256 digest
writing manifest
removing any unused layers
success

Ollama 允许用户用 Modelfile 创建自己的模型,写法与 Dockerfile 类型。这里以 llama 3.1 为基础,设置系统 prompt:

$ cat <<EOF > Modelfile
> FROM llama3.1 # set the temperature to 1 [higher is more creative, lower is more coherent]
PARAMETER temperature 1 # set the system message
SYSTEM """
You are a literary writer named Rora. Please help me polish my writing.
"""
> EOF
$
$ ollama create writer -f ./Modelfile
transferring model data
using existing layer sha256:8eeb52dfb3bb9aefdf9d1ef24b3bdbcfbe82238798c4b918278320b6fcef18fe
using existing layer sha256:11ce4ee3e170f6adebac9a991c22e22ab3f8530e154ee669954c4bc73061c258
using existing layer sha256:0ba8f0e314b4264dfd19df045cde9d4c394a52474bf92ed6a3de22a4ca31a177
creating new layer sha256:1dfe258ba02ecec9bf76292743b48c2ce90aefe288c9564c92d135332df6e514
creating new layer sha256:7fa4d1c192726882c2c46a2ffd5af3caddd99e96404e81b3cf2a41de36e25991
creating new layer sha256:ddb2d799341563f3da053b0da259d18d8b00b2f8c5951e7c5e192f9ead7d97ad
writing manifest
success

查看模型列表:

$  ollama list
NAME            ID           SIZE   MODIFIED
writer:latest   346a60dbd7d4 4.7 GB 17 minutes ago
llama3.1:latest 91ab477bec9d 4.7 GB 4 hours ago

03 到处运行

现在 JuiceFS 文件系统中就已经包含了用 Ollama 拉取的大模型了,所以在其他地方只要挂载上 JuiceFS,就可以直接运行了。本文分别演示在 Linux、Mac、Kubernetes 中用 Ollama 运行大模型。

Linux

在已经挂载了 JuiceFS 的机器上可以直接运行:

$ ollama run writer
>>> The flower is beautiful
A lovely start, but let's see if we can't coax out a bit more poetry from your words. How about this: "The flower unfolded its petals like a gentle whisper, its beauty an unassuming serenade that drew the eye and stirred the soul." Or, perhaps a slightly more concise version: "In the flower's delicate face, I find a beauty that soothes the senses and whispers secrets to the heart." Your turn! What inspired you to write about the flower?

Mac

挂载 JuiceFS:

weiwei@hdls-mbp ~ juicefs mount weiwei .llama --subdir=ollama
.OK, weiwei is ready at /Users/weiwei/.llama.

点击链接安装:https://ollama.com/download/Ollama-darwin.zip

这里需要注意的是,刚才拉取模型时,是以 root 存储的,所以在 Mac 上需要切换到 root 才能运行 ollama。

如果使用手动创建的 writer 模型,有个问题,新建的模型的 layer 写入的时候权限是 600,只有手动将其设置为 644 才可以在 Mac 上运行。这是 Ollama 的一个 bug,笔者已经向 Ollama 提了 PR

https://github.com/ollama/ollama/pull/6386)。但截止目前还没有发布新版本。临时解决方法如下:

hdls-mbp:~ root# cd /Users/weiwei/.ollama/models/blobs
hdls-mbp:blobs root# ls -alh . | grep rw-------
-rw-------   1 root  wheel    14B  8 15 23:04 sha256-804a1f079a1166190d674bcfb0fa42270ec57a4413346d20c5eb22b26762d132
-rw-------   1 root  wheel   559B  8 15 23:04 sha256-db7eed3b8121ac22a30870611ade28097c62918b8a4765d15e6170ec8608e507
hdls-mbp:blobs root#
hdls-mbp:blobs root#  chmod 644 sha256-804a1f079a1166190d674bcfb0fa42270ec57a4413346d20c5eb22b26762d132 sha256-db7eed3b8121ac22a30870611ade28097c62918b8a4765d15e6170ec8608e507
hdls-mbp:blobs root#
hdls-mbp:blobs root#
hdls-mbp:blobs root#
hdls-mbp:blobs root# ollama list
NAME            ID           SIZE   MODIFIED
writer:latest   346a60dbd7d4 4.7 GB About an hour ago
llama3.1:latest 91ab477bec9d 4.7 GB 4 hours ago

运行 writer 模型,并让其帮我们润色文字:

hdls-mbp:weiwei root# ollama run writer
>>> The tree is very tall
A great start, but let's see if we can make it even more vivid and engaging. Here's a revised version: "The tree stood sentinel, its towering presence stretching towards the sky like a verdant giant, its branches dancing
in the breeze with an elegance that seemed almost otherworldly." Or, if you'd prefer something simpler yet still evocative, how about this: "The tree loomed tall and green, its trunk sturdy as a stone pillar, its leaves a soft susurrus of sound in the gentle
wind." Which one resonates with you? Or do you have any specific ideas or feelings you want to convey through your writing
that I can help shape into a compelling phrase?

Kubernetes

JuiceFS 提供了 CSI Driver,使得用户可以在 Kubernetes 中直接使用 PV,支持静态配置和动态配置。由于我们是直接使用文件系统里已有的文件,所以这里使用静态配置。

准备 PVC 和 PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: ollama-vol
  labels:
    juicefs-name: ollama-vol
spec:
  capacity:
    storage: 10Pi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: csi.juicefs.com
    volumeHandle: ollama-vol
    fsType: juicefs
    nodePublishSecretRef:
      name: ollama-vol
      namespace: kube-system
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ollama-vol
  namespace: default
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 10Gi
  selector:
    matchLabels:
      juicefs-name: ollama-vol

部署 Ollama:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ollama
  labels:
    app: ollama
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ollama
  template:
    metadata:
      labels:
        app: ollama
    spec:
      containers:
      - image: registry.cn-hangzhou.aliyuncs.com/hdls/ollama:0.3.5
        env:
        - name: OLLAMA_HOST
          value: "0.0.0.0"
        ports:
        - name: ollama
          containerPort: 11434
        args:
        - "serve"
        name: ollama
        volumeMounts:
        - mountPath: /root/.ollama
          name: shared-data
          subPath: ollama
      volumes:
      - name: shared-data
        persistentVolumeClaim:
          claimName: ollama-vol
---
apiVersion: v1
kind: Service
metadata:
  name: ollama-svc
spec:
  selector:
    app: ollama
  ports:
    - name: http
      protocol: TCP
      port: 11434
      targetPort: 11434

由于 Ollama deployment 部署了一个 Ollama server,可以用 api 的方式访问:

$ curl http://192.168.203.37:11434/api/generate -d '{
  "model": "writer",
  "prompt": "The sky is blue",
  "stream": false
}'
{"model":"writer","created_at":"2024-08-15T14:35:43.593740142Z","response":"A starting point, at least! Let's see... How about we add some depth to this sentence? Here are a few suggestions:\n\n* Instead of simply stating that the sky is blue, why not describe how it makes you feel? For example: \"As I stepped outside, the cerulean sky seemed to stretch out before me like an endless canvas, its vibrant hue lifting my spirits and washing away the weight of the world.\"\n* Or, we could add some sensory details to bring the scene to life. Here's an example: \"The morning sun had just risen over the horizon, casting a warm glow across the blue sky that seemed to pulse with a gentle light – a softness that soothed my skin and lulled me into its tranquil rhythm.\"\n* If you're going for something more poetic, we could try to tap into the symbolic meaning of the sky's color. For example: \"The blue sky above was like an open door, inviting me to step through and confront the dreams I'd been too afraid to chase – a reminder that the possibilities are endless, as long as we have the courage to reach for them.\"\n\nWhich direction would you like to take this?","done":true,"done_reason":"stop","context":[128006,9125,128007,1432,2675,527,264,32465,7061,7086,432,6347,13,5321,1520,757,45129,856,4477,627,128009,128006,882,128007,271,791,13180,374,6437,128009,128006,78191,128007,271,32,6041,1486,11,520,3325,0,6914,596,1518,1131,2650,922,584,923,1063,8149,311,420,11914,30,5810,527,264,2478,18726,1473,9,12361,315,5042,28898,430,279,13180,374,6437,11,3249,539,7664,1268,433,3727,499,2733,30,1789,3187,25,330,2170,358,25319,4994,11,279,10362,1130,276,13180,9508,311,14841,704,1603,757,1093,459,26762,10247,11,1202,34076,40140,33510,856,31739,323,28786,3201,279,4785,315,279,1917,10246,9,2582,11,584,1436,923,1063,49069,3649,311,4546,279,6237,311,2324,13,5810,596,459,3187,25,330,791,6693,7160,1047,1120,41482,927,279,35174,11,25146,264,8369,37066,4028,279,6437,13180,430,9508,311,28334,449,264,22443,3177,1389,264,8579,2136,430,779,8942,291,856,6930,323,69163,839,757,1139,1202,68040,37390,10246,9,1442,499,2351,2133,369,2555,810,76534,11,584,1436,1456,311,15596,1139,279,36396,7438,315,279,13180,596,1933,13,1789,3187,25,330,791,6437,13180,3485,574,1093,459,1825,6134,11,42292,757,311,3094,1555,323,17302,279,19226,358,4265,1027,2288,16984,311,33586,1389,264,27626,430,279,24525,527,26762,11,439,1317,439,584,617,279,25775,311,5662,369,1124,2266,23956,5216,1053,499,1093,311,1935,420,30],"total_duration":13635238079,"load_duration":39933548,"prompt_eval_count":35,"prompt_eval_duration":55817000,"eval_count":240,"eval_duration":13538816000}

04 总结

Ollama 是一款简化了本地运行大模型的工具,将大模型拉取到本地,再使用简单的命令即可在本地运行自己的大模型。JuiceFS 可以充当大模型 Registry 的底层存储,由于其分布式的特征,使得用户可以在某处拉取一次模型后,在其他地方即可直接使用,从而实现了一次拉取,到处运行。

希望这篇内容能够对你有一些帮助,如果有其他疑问欢迎加入 JuiceFS 社区与大家共同交流。

Ollama + JuiceFS:一次拉取,到处运行的更多相关文章

  1. 从gitHub上拉取并运行项目

    今天我们来试一下如何从gitHub上拉取一个项目并且运行起来,话不多说,我们直接开搞可好 1.首先我们先获取到项目地址(此处我以自己的项目地址作为示例) 我们选择红圈处的clone or downlo ...

  2. Docker镜像-拉取并且运行

    1.docker search : 从Docker Hub查找镜像 docker search [OPTIONS] 镜像名 OPTIONS说明: --automated :只列出 automated ...

  3. docker镜像拉取、运行、删除

    1.拉取hello-world镜像并运行 docker pull hello-world 拉取hello-world镜像Using default tag: latestlatest: Pulling ...

  4. 005-docker-镜像使用、拉取、运行、创建、打tag

    当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载. 1.列出所有本地镜像 docker images ...

  5. mac+windows下从git上拉取项目及运行

    一.Mac下从git拉取项目 1. 拉项目 打开终端,先进入想放置项目的目录.假设进入workfile目录,输入cd workfile. 进入workfile目录后:输入git clone 链接(gi ...

  6. 【docker】【mysql】docker安装mysql,阿里云docker镜像加速器,docker搜索查看远程仓库上的镜像,docker拉取镜像,查看本地所有镜像,查看容器的运行状况,查看容器的详细信息

    在docker上安装mysql有两种方式 1.通过Dockerfile构建 2.直接在docker hub上拉取镜像安装 =================本篇采用方法2=============== ...

  7. Docker 拉取Nginx镜像 和运行

    Docker 镜像拉取 docker pull [OPTIONS] NAME[:TAG|@DIGEST] 镜像拉取命令 OPTIONS说明: -a :拉取所有 tagged 镜像 --disable- ...

  8. vscode提交修改的时候报错:无法推送 refs 到远端。您可以试着运行“拉取”功能,整合您的更改

    vscode提交修改的时候报错:无法推送 refs 到远端.您可以试着运行"拉取"功能,整合您的更改, git操作命令行 git pull origin yourbranch  - ...

  9. git中使用命令将远程仓库拉取项目在本地文件夹

    在有些时候,我们往往从github或者gitlab或者coding上面直接下载项目下来运行,但是这种情况往往没有使用git远程拉取来的安全(或者叫装逼), 所以这里我以gitLab为例子,说一下如何将 ...

  10. 自动备份远程mongodb数据库并拉取到本地

    自动备份远程mongodb数据库并拉取到本地 目标: 远程服务器 .1中的mongodb数据拉回公司测试服务器中 .远程服务器中编写自动备份mongodb脚本 ①编写脚本 # vim /opt/bac ...

随机推荐

  1. 运行前端React框架出现node Error: bind EADDRINUSE null的解决方法

    运行前端React代码时,出现这样的错误: node Error: bind EADDRINUSE null 后来发现端口号冲突,换个端口号后问题就可以解决了.

  2. SpringSecurity安全管理

    SpringSecurity安全管理 一.安全简介 在 Web 开发中,安全一直是非常重要的一个方面,因此从应用开发的第一天就应该把安全相关的因素考虑进来,并在整个应用的开发过程中. 主要安全框架:S ...

  3. 解决方案 | cad选择集找出包含特定字符串的多行文本

    代码如下: 1 # 选择文本中出现特定单词的多行文字 2 # 下面的代码将选择条件定义为文本字符串中出现"The"的任意选项.此示例还演示了选择方法的用法:MtextSelectB ...

  4. 27 首页banner文库失效

    安卓app 首页banner文库没有连接功能

  5. [oeasy]python0096_游戏娱乐行业_雅达利_米洛华_四人赛马_影视结合游戏

    游戏娱乐行业 回忆上次内容 游戏机行业从无到有 雅达利 公司 一枝独秀 并且带领 行业 发展起来 雅达利公司 优秀员工 乔布斯 在 朋友 帮助下完成了<pong> Jobs 黑了 Woz ...

  6. [oeasy]python0024_unix时间戳_epoch_localtime_asctime_PosixTime_unix纪年法

    输出时间回忆上次内容 通过搜索 我们学会 import 导入 time 了 完整写法为 asc_time = time.asctime( time.localtime( time.time())) 内 ...

  7. C# 对象复制三种方法效率对比——反射、序列化、表达式树

    1.需求 在代码中经常会遇到需要把对象复制一遍,或者把属性名相同的值复制一遍. 比如: public class Student { public int Id { get; set; } publi ...

  8. Fiddler使用界面介绍-底部状态栏

    底部状态栏 1.Capturing抓包状态 Capturing:Fiddler正在抓包 空白:Fiddler停止抓包 2.All Processes抓取进程类型 All Processes:抓取所有进 ...

  9. 【Java】单号创建服务

    需求:ERP项目存在若干个业务功能,每个业务的单子的单号创建规则需要被统一规划 1.每个业务有自己对应的标识 2.业务单号必须以英文字母为前缀,长度在2 - 4个字符 3.单号的组成 = [ 前缀 ] ...

  10. 【Java】JDBC Part5.1 Hikari连接池补充

    Hikari Connection Pool Hikari 连接池 HikariCP 官方文档 https://github.com/brettwooldridge/HikariCP Maven依赖 ...