重庆做网站好的公司,网站做淘宝客还行吗,ppt课件免费下载的网站,个人网站搭建本篇文章聊聊#xff0c;如何使用 Ollama、Dify 和 Docker 来完成本地 Llama 3.1 模型服务的搭建。
如果你需要将 Ollama 官方不支持的模型运行起来#xff0c;或者将新版本 llama.cpp 转换的模型运行起来#xff0c;并且想更轻松的使用 Dify 构建 AI 应用#xff0c;那么…本篇文章聊聊如何使用 Ollama、Dify 和 Docker 来完成本地 Llama 3.1 模型服务的搭建。
如果你需要将 Ollama 官方不支持的模型运行起来或者将新版本 llama.cpp 转换的模型运行起来并且想更轻松的使用 Dify 构建 AI 应用那么本文或许会对你有所帮助。
写在前面
最近这阵比较忙线下见了非常多不同地区的朋友围绕 Dify 和开源社区做了不少应用和实践分享。 不论是 Dify 生态还是其他的软件生态越来越多的朋友开始使用 Ollama 来了解模型。不过更多时候我们见到的是“下载预制菜”使用的玩法如果我们本地有微调好的模型又该如何运行呢
以及在最近 Llama.cpp 的一次版本发布中支持了 Llama 3.1 的“rope scaling factors”特性后新换后的通用模型其实并不能够被 Ollama 直接启动运行那么又该怎么处理呢
为了解决上面两个问题以及最近忙于线下分享没有写博客的问题这篇文章就来聊聊如何使用 Ollama 来完成“个性化的”模型服务搭建适合微调后的模型的推理使用呢
本文当然包含了上面这些问题的答案。 让我们开始实战。
准备工作
默认情况下我们的准备工作只有两项准备模型文件和准备 Ollama 运行程序。
本文中我们以 Llama 最新发布的 3.1 版本原始模型为例你可以参考这个方式来转换你的本地微调好的模型或者其他Ollama 官方不支持的模型。
下载模型
先来聊聊下载模型。
下载模型可以参考《节省时间AI 模型靠谱下载方案汇总》中提到的方法。
如果你的服务器或本地服务在国内可以使用 ModelScope社区已经有同学将 HuggingFace 上的 Llama 3.1 搬运到了模型库中8B、70B。
为了不影响我们的服务器或本地的环境可以创建一个独立的容器镜像环境来完成模型下载任务。
执行下面的命令能够创建一个持续运行的容器镜像
docker run -d --namedownloader -v pwd:/models python:3.10-slim tail -f /etc/hosts使用下面的命令进入容器的命令行环境
docker exec -it downloader bash接着进行一些简单的软件源加速配置
sed -i s/snapshot.debian.org/mirrors.tuna.tsinghua.edu.cn/g /etc/apt/sources.list.d/debian.sources
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
cd /models
pip install modelscope最后执行下面的命令开始具体模型的下载。
python -c from modelscope import snapshot_download;snapshot_download(LLM-Research/Meta-Llama-3.1-8B-Instruct, cache_dir./models/)以 8B 版本的模型为例完整仓库尺寸在 30GB如果你是千兆宽带满速下载时间大概只需要几分钟。
下载后的目录内容、主要模型的校验结果、目录尺寸如下
# ls
config.json LICENSE model-00003-of-00004.safetensors original tokenizer_config.json
configuration.json model-00001-of-00004.safetensors model-00004-of-00004.safetensors README.md tokenizer.json
generation_config.json model-00002-of-00004.safetensors model.safetensors.index.json special_tokens_map.json USE_POLICY.md# ls *.safetensors | xargs -I {} shasum {}
b8006f35b7d4a8a51a1bdf9d855eff6c8ee669fb model-00001-of-00004.safetensors
38a23f109de9fcdfb27120ab10c18afc3dac54b8 model-00002-of-00004.safetensors
5ebfe3caea22c3a16dc92d5e8be88605039fd733 model-00003-of-00004.safetensors
57d3f7ef9a903a0e4d119c69982cfc3e7c5b23e8 model-00004-of-00004.safetensors# du -hs .
30G下载 Ollama 的 Docker 镜像 我们可以在 Ollama 的 Docker 页面中找到所有可以下载的版本。
官方出于项目的可维护性省的写如何升级建议我们直接使用下面的命令来下载 ollama 的 Docker 镜像。
# 使用 CPU 或者 Nvidia GPU 来推理模型
docker pull ollama/ollama
# 使用 AMD GPU 来推理模型
docker pull ollama/ollama:rocm不过我个人还是建议我们始终使用具体的版本的镜像来确保我们的运行环境是明确的运行环境可维护性使用类似下面的方式下载镜像。
# CPU 或 Nvidia GPU 运行
docker pull ollama/ollama:0.3.0
# AMD 显卡运行
docker pull ollama/ollama:0.3.0-rocm针对不同的设备我们的运行指令也需要有不同的调整
# 默认 CPU 模式运行
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama# Nvidia GPU 模式运行
docker run -d --gpusall -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama# AMD 显卡运行
docker run -d --device /dev/kfd --device /dev/dri -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama:rocm使用 llama.cpp 转换模型程序
Ollama 的模型仓库默认提供了几十种可以直接运行的模型我们可以通过类似下面的命令快速获取预制菜。
ollama run llama3不过出于授人以渔的目的以及在许多场景下我们终究要运行自己 finetune 微调后的模型这里我们选择使用 Llama.cpp 来量化自己的模型为 Ollama 可以运行的格式。
在《零一万物模型折腾笔记官方 Yi-34B 模型基础使用》文章中的“尝试对模型进行几种不同的量化操作”、《本地运行“李开复”的零一万物 34B 大模型》中的“编译使用 GPU 的 llama.cpp”、《CPU 混合推理非常见大模型量化方案“二三五六” 位量化》三篇文章中我分别提到过 Llama.cpp 的 CPU 程序编译、GPU 程序编译、通用模型格式的量化操作。如果你感兴趣可以自行翻阅。
构建新版本的 llama.cpp
简单来说我们可以通过下面的方式来手动构建适合自己设备的 llama.cpp 程序
# 下载代码
git clone https://github.com/ggerganov/llama.cpp.git --depth1
# 切换工作目录
cd llama.cpp# 常规模式构建 llama.cpp
cmake -B build
cmake --build build --config Release# 如果你是 macOS希望使用 Apple Metal
GGML_NO_METAL1 cmake --build build --config Release# 如果你使用 Nvidia GPU
apt install nvidia-cuda-toolkit -y
cmake -B build -DGGML_CUDAON
cmake --build build --config Release当我们构建完毕 llama.cpp 后我们就能够对转换后的模型进行运行验证了。
通过 llama.cpp 转换模型格式
为了能够转换模型我们还需要安装一个简单的依赖
pip install sentencepiece 接下来就可以使用官方的新的转换脚本来完成模型从 Huggingface Safetensors 格式到通用模型格式 GGML 的转换啦。
# ./convert_hf_to_gguf.py ../LLM-Research/Meta-Llama-3___1-8B-InstructINFO:hf-to-gguf:Loading model: Meta-Llama-3___1-8B-Instruct
INFO:gguf.gguf_writer:gguf: This GGUF file is for Little Endian only
INFO:hf-to-gguf:Exporting model...
INFO:hf-to-gguf:gguf: loading model weight map from model.safetensors.index.json
INFO:hf-to-gguf:gguf: loading model part model-00001-of-00004.safetensors
INFO:hf-to-gguf:token_embd.weight, torch.bfloat16 -- F16, shape {4096, 128256}
INFO:hf-to-gguf:blk.0.attn_norm.weight, torch.bfloat16 -- F32, shape {4096}
INFO:hf-to-gguf:blk.0.ffn_down.weight, torch.bfloat16 -- F16, shape {14336, 4096}
INFO:hf-to-gguf:blk.0.ffn_gate.weight, torch.bfloat16 -- F16, shape {4096, 14336}
INFO:hf-to-gguf:blk.0.ffn_up.weight, torch.bfloat16 -- F16, shape {4096, 14336}
...
INFO:hf-to-gguf:Set model quantization version
INFO:gguf.gguf_writer:Writing the following files:
INFO:gguf.gguf_writer:../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf: n_tensors 292, total_size 16.1G
Writing: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 16.1G/16.1G [00:2400:00, 664Mbyte/s]
INFO:hf-to-gguf:Model successfully exported to ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf验证转换后模型
转换完的模型我们可以使用下面的命令来查看基本状况
# ./build/bin/llama-lookup-stats -m ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.ggufllama_model_loader: loaded meta data with 29 key-value pairs and 292 tensors from ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv 0: general.architecture str llama
llama_model_loader: - kv 1: general.type str model
llama_model_loader: - kv 2: general.name str Meta Llama 3___1 8B Instruct
llama_model_loader: - kv 3: general.finetune str 3___1-Instruct
llama_model_loader: - kv 4: general.basename str Meta-Llama
llama_model_loader: - kv 5: general.size_label str 8B
llama_model_loader: - kv 6: general.license str llama3.1
llama_model_loader: - kv 7: general.tags arr[str,6] [facebook, meta, pytorch, llam...
llama_model_loader: - kv 8: general.languages arr[str,8] [en, de, fr, it, pt, hi, ...
llama_model_loader: - kv 9: llama.block_count u32 32
llama_model_loader: - kv 10: llama.context_length u32 131072
llama_model_loader: - kv 11: llama.embedding_length u32 4096
llama_model_loader: - kv 12: llama.feed_forward_length u32 14336
llama_model_loader: - kv 13: llama.attention.head_count u32 32
llama_model_loader: - kv 14: llama.attention.head_count_kv u32 8
llama_model_loader: - kv 15: llama.rope.freq_base f32 500000.000000
llama_model_loader: - kv 16: llama.attention.layer_norm_rms_epsilon f32 0.000010
llama_model_loader: - kv 17: general.file_type u32 1
llama_model_loader: - kv 18: llama.vocab_size u32 128256
llama_model_loader: - kv 19: llama.rope.dimension_count u32 128
llama_model_loader: - kv 20: tokenizer.ggml.model str gpt2
llama_model_loader: - kv 21: tokenizer.ggml.pre str llama-bpe
llama_model_loader: - kv 22: tokenizer.ggml.tokens arr[str,128256] [!, \, #, $, %, , , ...
llama_model_loader: - kv 23: tokenizer.ggml.token_type arr[i32,128256] [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
llama_model_loader: - kv 24: tokenizer.ggml.merges arr[str,280147] [Ġ Ġ, Ġ ĠĠĠ, ĠĠ ĠĠ, ...
llama_model_loader: - kv 25: tokenizer.ggml.bos_token_id u32 128000
llama_model_loader: - kv 26: tokenizer.ggml.eos_token_id u32 128009
llama_model_loader: - kv 27: tokenizer.chat_template str {% set loop_messages messages %}{% ...
llama_model_loader: - kv 28: general.quantization_version u32 2
llama_model_loader: - type f32: 66 tensors
llama_model_loader: - type f16: 226 tensors
llm_load_vocab: special tokens cache size 256
llm_load_vocab: token to piece cache size 0.7999 MB
llm_load_print_meta: format GGUF V3 (latest)
llm_load_print_meta: arch llama
llm_load_print_meta: vocab type BPE
llm_load_print_meta: n_vocab 128256
llm_load_print_meta: n_merges 280147
llm_load_print_meta: vocab_only 0
llm_load_print_meta: n_ctx_train 131072
llm_load_print_meta: n_embd 4096
llm_load_print_meta: n_layer 32
llm_load_print_meta: n_head 32
llm_load_print_meta: n_head_kv 8
llm_load_print_meta: n_rot 128
llm_load_print_meta: n_swa 0
llm_load_print_meta: n_embd_head_k 128
llm_load_print_meta: n_embd_head_v 128
llm_load_print_meta: n_gqa 4
llm_load_print_meta: n_embd_k_gqa 1024
llm_load_print_meta: n_embd_v_gqa 1024
llm_load_print_meta: f_norm_eps 0.0e00
llm_load_print_meta: f_norm_rms_eps 1.0e-05
llm_load_print_meta: f_clamp_kqv 0.0e00
llm_load_print_meta: f_max_alibi_bias 0.0e00
llm_load_print_meta: f_logit_scale 0.0e00
llm_load_print_meta: n_ff 14336
llm_load_print_meta: n_expert 0
llm_load_print_meta: n_expert_used 0
llm_load_print_meta: causal attn 1
llm_load_print_meta: pooling type 0
llm_load_print_meta: rope type 0
llm_load_print_meta: rope scaling linear
llm_load_print_meta: freq_base_train 500000.0
llm_load_print_meta: freq_scale_train 1
llm_load_print_meta: n_ctx_orig_yarn 131072
llm_load_print_meta: rope_finetuned unknown
llm_load_print_meta: ssm_d_conv 0
llm_load_print_meta: ssm_d_inner 0
llm_load_print_meta: ssm_d_state 0
llm_load_print_meta: ssm_dt_rank 0
llm_load_print_meta: model type 8B
llm_load_print_meta: model ftype F16
llm_load_print_meta: model params 8.03 B
llm_load_print_meta: model size 14.96 GiB (16.00 BPW)
llm_load_print_meta: general.name Meta Llama 3___1 8B Instruct
llm_load_print_meta: BOS token 128000 |begin_of_text|
llm_load_print_meta: EOS token 128009 |eot_id|
llm_load_print_meta: LF token 128 Ä
llm_load_print_meta: EOT token 128009 |eot_id|
llm_load_print_meta: max token length 256
ggml_cuda_init: GGML_CUDA_FORCE_MMQ: no
ggml_cuda_init: GGML_CUDA_FORCE_CUBLAS: no
ggml_cuda_init: found 1 CUDA devices:Device 0: NVIDIA GeForce RTX 4090, compute capability 8.9, VMM: yes
llm_load_tensors: ggml ctx size 0.14 MiB
llm_load_tensors: offloading 0 repeating layers to GPU
llm_load_tensors: offloaded 0/33 layers to GPU
llm_load_tensors: CPU buffer size 15317.02 MiB
.........................................................................................
llama_new_context_with_model: n_ctx 131072
llama_new_context_with_model: n_batch 2048
llama_new_context_with_model: n_ubatch 512
llama_new_context_with_model: flash_attn 0
llama_new_context_with_model: freq_base 500000.0
llama_new_context_with_model: freq_scale 1
llama_kv_cache_init: CUDA_Host KV buffer size 16384.00 MiB
llama_new_context_with_model: KV self size 16384.00 MiB, K (f16): 8192.00 MiB, V (f16): 8192.00 MiB
llama_new_context_with_model: CUDA_Host output buffer size 0.49 MiB
llama_new_context_with_model: CUDA0 compute buffer size 8984.00 MiB
llama_new_context_with_model: CUDA_Host compute buffer size 264.01 MiB
llama_new_context_with_model: graph nodes 1030
llama_new_context_with_model: graph splits 420n_draft 5
n_predict 0
n_drafted 0
t_draft_flat 0.00 ms
t_draft 0.00 ms, -nan us per token, -nan tokens per second
n_accept 0
accept -nan%当然也可以“跑个分”
# ./build/bin/llama-bench -m ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.ggufggml_cuda_init: GGML_CUDA_FORCE_MMQ: no
ggml_cuda_init: GGML_CUDA_FORCE_CUBLAS: no
ggml_cuda_init: found 1 CUDA devices:Device 0: NVIDIA GeForce RTX 4090, compute capability 8.9, VMM: yes
| model | size | params | backend | ngl | test | t/s |
| ------------------------------ | ---------: | ---------: | ---------- | --: | ------------: | ---------------: |
| llama 8B F16 | 14.96 GiB | 8.03 B | CUDA | 99 | pp512 | 10909.62 ± 38.48 |
| llama 8B F16 | 14.96 GiB | 8.03 B | CUDA | 99 | tg128 | 56.51 ± 0.04 |或者使用 simple 程序来完成上面两个命令的“打包操作”
# ./build/bin/llama-simple -m ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf...
ggml_cuda_init: GGML_CUDA_FORCE_MMQ: no
ggml_cuda_init: GGML_CUDA_FORCE_CUBLAS: no
ggml_cuda_init: found 1 CUDA devices:Device 0: NVIDIA GeForce RTX 4090, compute capability 8.9, VMM: yes
llm_load_tensors: ggml ctx size 0.14 MiB
llm_load_tensors: offloading 0 repeating layers to GPU
llm_load_tensors: offloaded 0/33 layers to GPU
llm_load_tensors: CPU buffer size 15317.02 MiB
.........................................................................................
llama_new_context_with_model: n_ctx 131072
llama_new_context_with_model: n_batch 2048
llama_new_context_with_model: n_ubatch 512
llama_new_context_with_model: flash_attn 0
llama_new_context_with_model: freq_base 500000.0
llama_new_context_with_model: freq_scale 1
llama_kv_cache_init: CUDA_Host KV buffer size 16384.00 MiB
llama_new_context_with_model: KV self size 16384.00 MiB, K (f16): 8192.00 MiB, V (f16): 8192.00 MiB
llama_new_context_with_model: CUDA_Host output buffer size 0.49 MiB
llama_new_context_with_model: CUDA0 compute buffer size 8984.00 MiB
llama_new_context_with_model: CUDA_Host compute buffer size 264.01 MiB
llama_new_context_with_model: graph nodes 1030
llama_new_context_with_model: graph splits 420main: n_predict 32, n_ctx 131072, n_kv_req 32|begin_of_text|Hello my name is Emily and I am a 25 year old artist living in the beautiful city of Portland, Oregon. I am a painter and a printmain: decoded 27 tokens in 7.64 s, speed: 3.54 t/sllama_print_timings: load time 5626.11 ms
llama_print_timings: sample time 5.47 ms / 28 runs ( 0.20 ms per token, 5122.58 tokens per second)
llama_print_timings: prompt eval time 506.98 ms / 5 tokens ( 101.40 ms per token, 9.86 tokens per second)
llama_print_timings: eval time 7598.61 ms / 27 runs ( 281.43 ms per token, 3.55 tokens per second)
llama_print_timings: total time 13260.46 ms / 32 tokens验证完转换的模型是正确并且能够运行的之后这里我们可以选择根据自己的硬件情况进行一些量化操作来降低模型运行对硬件的需求。
对转换后的通用模型进行量化
默认情况下llama.cpp 支持以下的量化方式
Allowed quantization types:2 or Q4_0 : 4.34G, 0.4685 ppl Llama-3-8B3 or Q4_1 : 4.78G, 0.4511 ppl Llama-3-8B8 or Q5_0 : 5.21G, 0.1316 ppl Llama-3-8B9 or Q5_1 : 5.65G, 0.1062 ppl Llama-3-8B19 or IQ2_XXS : 2.06 bpw quantization20 or IQ2_XS : 2.31 bpw quantization28 or IQ2_S : 2.5 bpw quantization29 or IQ2_M : 2.7 bpw quantization24 or IQ1_S : 1.56 bpw quantization31 or IQ1_M : 1.75 bpw quantization10 or Q2_K : 2.96G, 3.5199 ppl Llama-3-8B21 or Q2_K_S : 2.96G, 3.1836 ppl Llama-3-8B23 or IQ3_XXS : 3.06 bpw quantization26 or IQ3_S : 3.44 bpw quantization27 or IQ3_M : 3.66 bpw quantization mix12 or Q3_K : alias for Q3_K_M22 or IQ3_XS : 3.3 bpw quantization11 or Q3_K_S : 3.41G, 1.6321 ppl Llama-3-8B12 or Q3_K_M : 3.74G, 0.6569 ppl Llama-3-8B13 or Q3_K_L : 4.03G, 0.5562 ppl Llama-3-8B25 or IQ4_NL : 4.50 bpw non-linear quantization30 or IQ4_XS : 4.25 bpw non-linear quantization15 or Q4_K : alias for Q4_K_M14 or Q4_K_S : 4.37G, 0.2689 ppl Llama-3-8B15 or Q4_K_M : 4.58G, 0.1754 ppl Llama-3-8B17 or Q5_K : alias for Q5_K_M16 or Q5_K_S : 5.21G, 0.1049 ppl Llama-3-8B17 or Q5_K_M : 5.33G, 0.0569 ppl Llama-3-8B18 or Q6_K : 6.14G, 0.0217 ppl Llama-3-8B7 or Q8_0 : 7.96G, 0.0026 ppl Llama-3-8B33 or Q4_0_4_4 : 4.34G, 0.4685 ppl Llama-3-8B34 or Q4_0_4_8 : 4.34G, 0.4685 ppl Llama-3-8B35 or Q4_0_8_8 : 4.34G, 0.4685 ppl Llama-3-8B1 or F16 : 14.00G, 0.0020 ppl Mistral-7B32 or BF16 : 14.00G, -0.0050 ppl Mistral-7B0 or F32 : 26.00G 7BCOPY : only copy tensors, no quantizing我个人通常会选择 Q4_K_M 一类的量化类型保持小巧又不会太掉性能你可以根据自己的习惯来进行量化
# ./build/bin/llama-quantize ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf Q4_K_M
main: build 1 (4730fac)
main: built with cc (Ubuntu 13.2.0-23ubuntu4) 13.2.0 for x86_64-linux-gnu
main: quantizing ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf to ../LLM-Research/Meta-Llama-3___1-8B-Instruct/ggml-model-Q4_K_M.gguf as Q4_K_M
llama_model_loader: loaded meta data with 29 key-value pairs and 292 tensors from ../LLM-Research/Meta-Llama-3___1-8B-Instruct/Meta-Llama-8B-3___1-Instruct-F16.gguf (version GGUF V3 (latest))
llama_model_loader: Dumping metadata keys/values. Note: KV overrides do not apply in this output.
llama_model_loader: - kv 0: general.architecture str llama
...
[ 290/ 292] blk.31.ffn_down.weight - [14336, 4096, 1, 1], type f16, converting to q6_K .. size 112.00 MiB - 45.94 MiB
[ 291/ 292] blk.31.ffn_norm.weight - [ 4096, 1, 1, 1], type f32, size 0.016 MB
[ 292/ 292] output_norm.weight - [ 4096, 1, 1, 1], type f32, size 0.016 MB
llama_model_quantize_internal: model size 15317.02 MB
llama_model_quantize_internal: quant size 4685.30 MBmain: quantize time 22881.80 ms
main: total time 22881.80 ms我们可以使用上文中的方式对量化后的模型再次进行验证
# ./build/bin/llama-simple -m ../LLM-Research/Meta-Llama-3___1-8B-Instruct/ggml-model-Q4_K_M.gguf main: decoded 27 tokens in 2.47 s, speed: 10.93 t/sllama_print_timings: load time 5247.69 ms
llama_print_timings: sample time 4.08 ms / 28 runs ( 0.15 ms per token, 6857.70 tokens per second)
llama_print_timings: prompt eval time 179.68 ms / 5 tokens ( 35.94 ms per token, 27.83 tokens per second)
llama_print_timings: eval time 2445.16 ms / 27 runs ( 90.56 ms per token, 11.04 tokens per second)
llama_print_timings: total time 7718.22 ms / 32 tokens可以看到默认情况下使用 CPU 进行推理的速度就提升了 3 倍。
接下来我们来使用 Docker 和 Ollama 来运行刚刚量化好的模型完成服务的搭建。
Ollama 服务的启动
当我们搞定 Ollama 可以导入的模型文件之后就可以开始折腾 Ollama 啦。
完成 Ollama 模型的构建
我们可以创建一个干净的目录将刚刚在其他目录中量化好的模型放进来创建一个 ollama 模型配置文件方便后续的操作
# 创建一个新的工作目录
mkdir ollama
# 切换工作目录
cd ollama
# 将量化好的模型放到目录中
cp ../llama3/LLM-Research/Meta-Llama-3___1-8B-Instruct/ggml-model-Q4_K_M.gguf .
# 创建一个 ollama 模型配置文件
echo FROM ./ggml-model-Q4_K_M.gguf Modelfile然后使用上文中提到的命令将服务运行起来
docker run -d --gpusall -v pwd:/root/.ollama -p 11434:11434 --name ollama-llama3 ollama/ollama:0.3.0接着使用下面的命令进入 ollama 容器交互命令行环境
docker exec -it ollama-llama3 bash 执行下面的命令完成 ollama 模型的导入
ollama create custom_llama_3_1 -f ~/.ollama/Modelfile正常情况下我们将看到类似下面的日志输出
transferring model data
using existing layer sha256:c6f9cdd9aca1c9bc25d63c4175261ca16cc9d8c283d0e696ad9eefe56cf8400f
using autodetected template llama3-instruct
creating new layer sha256:0c41faf4e1ecc31144e8f17ec43fb74f81318a2672ee88088e07c09a680f2212
writing manifest
success 导入模型后我们可以通过 show 命令来查看模型的基础状况
# ollama show custom_llama_3_1Model arch llama parameters 8.0B quantization Q4_K_M context length 131072 embedding length 4096 转换完毕的模型会保存在 ~/.ollama/models 目录中。
du -hs ~/.ollama/models/
4.6G /root/.ollama/models/因为我们刚刚在启动服务的时候已经在模型目录映射到了本地所以接下来我们只需要重新创建一个容器携带合适的命令就能够完成服务的搭建了而无需再次构建 ollama 镜像。
启动 Ollama 模型服务
通常情况下如果已经完成了模型的转换我们可以结合上文中的命令进行调整在命令后添加要执行的模型来完成服务的启动
docker run -d --gpusall -v pwd:/root/.ollama -p 11434:11434 --name ollama-llama3 ollama/ollama:0.3.0不过最近 llama.cpp 有更新更新后的模型 ollama 是无法启动的我们需要从源码重新构建 Ollama 镜像。
当然为了更简单的解决问题我已经将构建好的镜像上传到了 DockerHub我们可以使用下面的命令来下载这个 CPU 和 N 卡通用的镜像AMD Rocm镜像比较大如果有需要我再上传吧。
docker pull soulteary/ollama:0.3.0-fix然后将命令替换为
docker run -d --gpusall -v pwd:/root/.ollama -p 11434:11434 --name ollama-llama3 soulteary/ollama:0.3.0-fix接下来我们就可以通过 API 来调用 Ollama 服务运行我们的自定义模型啦custom_llama_3_1。
curl http://localhost:11434/api/generate -d {model: custom_llama_3_1,prompt:Why is the sky blue?
}调用后的输出结果类似下面这样
{model:custom_llama_3_1,created_at:2024-07-28T12:59:05.390939108Z,response:The,done:false}
{model:custom_llama_3_1,created_at:2024-07-28T12:59:05.390944605Z,response: sky,done:false}
{model:custom_llama_3_1,created_at:2024-07-28T12:59:05.391066439Z,response: appears,done:false}
{model:custom_llama_3_1,created_at:2024-07-28T12:59:05.391068088Z,response: blue,done:false}
...
{model:custom_llama_3_1,created_at:2024-07-28T12:59:08.259730694Z,response: atmosphere,done:false}
{model:custom_llama_3_1,created_at:2024-07-28T12:59:08.268042795Z,response:.,done:false}
{model:custom_llama_3_1,created_at:2024-07-28T12:59:08.276441118Z,response:,done:true,done_reason:stop,context:[128006,882,128007,271,10445,374,279,13180,6437,30,128009,128006,78191,128007,271,791,13180,8111,6437,311,603,1606,315,264,25885,2663,72916,11,902,13980,994,40120,84261,449,279,13987,35715,315,45612,304,279,9420,596,16975,13,5810,596,264,44899,16540,1473,16,13,3146,31192,4238,29933,9420,596,16975,96618,3277,40120,29933,1057,16975,11,433,17610,315,682,279,8146,315,279,9621,20326,11,2737,2579,11,19087,11,14071,11,6307,11,6437,11,1280,7992,11,323,80836,627,17,13,3146,3407,31436,13980,96618,578,24210,320,12481,8,93959,527,38067,304,682,18445,555,279,13987,35715,315,45612,1778,439,47503,320,45,17,8,323,24463,320,46,17,570,1115,374,3967,439,13558,64069,72916,11,7086,1306,279,8013,83323,10425,13558,64069,11,889,1176,7633,279,25885,304,279,3389,220,777,339,9478,627,18,13,3146,6720,261,93959,1522,1555,96618,578,5129,93959,11,1093,2579,323,19087,11,527,539,38067,439,1790,323,3136,311,5944,304,264,7833,1584,11,19261,1057,6548,505,810,2167,13006,627,19,13,3146,8140,6548,45493,279,1933,96618,3277,584,1427,520,279,13180,11,1057,6548,5371,279,38067,6437,3177,505,682,18445,11,902,374,3249,433,8111,6437,382,8538,5217,9547,430,10383,279,10186,1933,315,279,13180,2997,1473,9,3146,1688,8801,33349,4787,96618,578,3392,315,16174,11,83661,11,323,3090,38752,304,279,16975,649,7958,1268,1790,40120,374,38067,627,9,3146,1489,315,1938,323,1060,96618,578,2361,315,279,7160,323,279,9392,315,40120,16661,279,16975,649,1101,5536,279,26617,1933,315,279,13180,627,9,3146,16440,82,323,25793,96618,15161,82,323,83661,304,279,3805,649,45577,3177,304,2204,5627,11,7170,3339,279,13180,5101,810,305,13933,477,18004,382,4516,11,311,63179,25,279,13180,8111,6437,1606,315,279,72916,315,24210,320,12481,8,93959,315,40120,555,13987,35715,304,279,9420,596,16975,13],total_duration:4835140836,load_duration:1865770271,prompt_eval_count:16,prompt_eval_duration:12268000,eval_count:356,eval_duration:2913570000}
当然为了更直观我们可以使用 Dify 来调用 Ollama 的 API构建 AI 应用。这个内容我们在本文的下一小节展开。
从源码构建 Ollama 程序镜像
想要从源码构建 Ollama 并不复杂但是我们需要做一些准备工作。
# 下载仓库代码
git clone https://github.com/ollama/ollama.git ollama-src
# 切换代码目录
cd ollama-src
# 进入核心组件目录
cd llm
# 更新组件代码
git submodule update --init --recursive
# 更新 llama.cpp 主分支相关代码
cd llama.cpp
git checkout master
git pull完成代码的获取后我们可以根据需要进行容器的构建
# 回到代码根目录
cd ../../
# 构建修补后或调整后的程序镜像
bash scripts/build_docker.sh
# 你也可以在命令前添加你希望构建的架构减少构建时间
BUILD_ARCHamd64 bash scripts/build_docker.sh作者并没有针对 Docker 构建做优化所以构建时间会相对的长一些
BUILD_ARCHamd64 bash scripts/build_docker.sh
[] Building 27.4s (48/48) FINISHED docker:default [internal] load build definition from Dockerfile 0.0s transferring dockerfile: 6.25kB 0.0s [internal] load .dockerignore 0.0s transferring context: 107B 0.0s [internal] load metadata for docker.io/nvidia/cuda:11.3.1-devel-centos7 1.7s [internal] load metadata for docker.io/library/ubuntu:22.04 0.0s [internal] load metadata for docker.io/rocm/dev-centos-7:6.1.2-complete 1.7s [internal] load metadata for docker.io/library/centos:7 1.7s [auth] nvidia/cuda:pull token for registry-1.docker.io 0.0s [auth] rocm/dev-centos-7:pull token for registry-1.docker.io 0.0s [auth] library/centos:pull token for registry-1.docker.io 0.0s [runtime-amd64 1/3] FROM docker.io/library/ubuntu:22.04
... [runtime-rocm 3/3] COPY --frombuild-amd64 /go/src/github.com/ollama/ollama/ollama /bin/ollama 0.4s exporting to image 1.9s exporting layers 1.9s writing image sha256:c8f45a6cf0e212476d61757e5ef1e9d279be45369f87c5f0e362d42f4f41713f 0.0s naming to docker.io/ollama/release:0.3.0-12-gf3d7a48-dirty-rocm 0.0s
Skipping manifest generation when not pushing images are available locally as ollama/release:0.3.0-12-gf3d7a48-dirty-amd64ollama/release:0.3.0-12-gf3d7a48-dirty-arm64ollama/release:0.3.0-12-gf3d7a48-dirty-rocm完成构建后我们将得到上面输出的几个拥有很长名称的 Docker 镜像为了更好的维护和使用我们可以给镜像起个合适的名字
docker tag ollama/release:0.3.0-12-gf3d7a48-dirty-amd64 soulteary/ollama:0.3.0-fix这个镜像我已经上传到了 DockerHub有需要的同学可以直接下载使用
docker pull soulteary/ollama:0.3.0-fixOllama 在 Dify 中的使用
关于 Dify 的实战内容我之前已经写过了一些如果你感兴趣可以阅读这里了解各种有趣的使用方法。之前提到的一些内容我就不再展开。 想要在 Dify 中愉快的使用 Ollama 的 API我们需要先打开“设置”中的“添加模型”界面选择 Ollama。 参考上文中的信息我们完成包括模型名称、模型配置参数的填写点击“保存”完成新模型的添加。 返回 Dify 的主界面创建一个新的 AI 应用随便起个名字我这里使用的是“Llama 3.1 Ollama 接口验证”。 在新建的 AI 应用界面选择刚刚添加的 Ollama 模型。 接下来就是愉快的 Dify 时间根据你的需要来和 Ollama 模型进行交互啦。如果你对具体的应用玩法感兴趣可以参考我之前写过的 Dify 相关的实战内容。
最后
接下来的相关内容让我们继续聊聊今年下半年“大模型”新赛季版本的一些有趣玩法升级吧。
下一篇文章见。
–EOF 我们有一个小小的折腾群里面聚集了一些喜欢折腾、彼此坦诚相待的小伙伴。
我们在里面会一起聊聊软硬件、HomeLab、编程上、生活里以及职场中的一些问题偶尔也在群里不定期的分享一些技术资料。
关于交友的标准请参考下面的文章
致新朋友为生活投票不断寻找更好的朋友
当然通过下面这篇文章添加好友时请备注实名和公司或学校、注明来源和目的珍惜彼此的时间
关于折腾群入群的那些事 本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议欢迎转载、或重新修改使用但需要注明来源。 署名 4.0 国际 (CC BY 4.0)
本文作者: 苏洋
创建时间: 2024年07月28日 统计字数: 24171字 阅读时间: 49分钟阅读 本文链接: https://soulteary.com/2024/07/28/build-llama-3-1-model-service-from-scratch-using-ollama-dify-and-docker.html