zhulink logo
自动夜间模式 日间模式 夜间模式
侧栏
0

Hugging Face Spaces × Docker 部署 Ollama 小模型全流程

意外富翁的头像
|
|
|
把 **Ollama** 装进 **Hugging Face Spaces** 的免费 Docker 容器,让 1-4B 小模型一键上线,随时通过 HTTPS 调用。 --- ## 1 创建 Spaces 容器 1. 登录 [https://huggingface.co](https://huggingface.co) → 右上角 **New Space** 2. Space 名称随意(例 `ollama-gemma`)、**Docker** 类型、硬件选 **CPU basic**(免费 2 vCPU / 16 GB,足够 1-4B 量化模型)。 3. 选 **Public**(私有需 PRO),点 **Create Space**。 --- ## 2 本地克隆仓库(后面要推送) ```bash git clone https://huggingface.co/spaces/<你的用户名>/ollama-gemma cd ollama-gemma ``` --- ## 3 一键可用文件清单(全部放在仓库根目录) | 文件 | 作用 | |---|---| | `Dockerfile` | 基于 ollama/ollama 官方镜像,装 Python、依赖、暴露 7860 | | `entrypoint.sh` | 启动 ollama 服务 → 拉模型 → 启动 FastAPI 代理 | | `app.py` | 透传 `/generate` 接口,把客户端 JSON 原样发给 Ollama | | `requirements.txt` | 仅 3 行:fastapi / uvicorn / requests | 下面直接给出内容,复制即可。 ### 3.1 Dockerfile ```dockerfile # 使用 ollama 官方镜像作为底包 FROM ollama/ollama:latest # 1. 安装系统依赖(curl + python3) RUN apt-get update && \ apt-get install -y --no-install-recommends \ curl \ python3 \ python3-pip \ python3-venv \ python-is-python3 && \ rm -rf /var/lib/apt/lists/* # 2. 创建并启用虚拟环境(避开 PEP-668 限制) RUN python3 -m venv /opt/venv ENV PATH="/opt/venv/bin:$PATH" # 3. 复制 requirements 并安装 Python 依赖 COPY requirements.txt /tmp/ RUN pip install --upgrade pip && \ pip install -r /tmp/requirements.txt # 4. 复制业务代码 WORKDIR /code COPY . . # 5. 暴露 Hugging Face 要求的端口 EXPOSE 7860 # 6. 启动脚本 ENTRYPOINT ["bash", "entrypoint.sh"] ``` ### 3.2 entrypoint.sh ```bash #!/bin/bash set -e # 设置环境变量 export OLLAMA_MAX_LOADED_MODELS=2 echo "Set OLLAMA_MAX_LOADED_MODELS=$OLLAMA_MAX_LOADED_MODELS" echo "Set OLLAMA_KEEP_ALIVE=-1" echo "Starting Ollama service..." # 1. 后台启动 ollama 服务 ollama serve & OLLAMA_PID=$! # 等待服务就绪(最多等待120秒) echo "Waiting for Ollama to be ready..." COUNTER=0 until curl -s http://localhost:11434/api/tags > /dev/null 2>&1; do echo "Waiting for Ollama... ($COUNTER/120)" sleep 3 COUNTER=$((COUNTER + 3)) if [ $COUNTER -ge 120 ]; then echo "ERROR: Ollama failed to start within 120 seconds" kill $OLLAMA_PID 2>/dev/null || true exit 1 fi done echo "Ollama is ready!" # 2. 拉取模型 echo "Pulling models..." ollama pull nomic-embed-text || echo "Failed to pull nomic-embed-text" ollama pull qwen2.5:1.5b || echo "Failed to pull qwen2.5:1.5b" # 3. 保持模型在内存中运行 echo "Loading models into memory..." # 启动 nomic-embed-text 模型并保持运行 ollama run nomic-embed-text > /dev/null 2>&1 & EMBED_PID=$! # 启动 qwen2.5:1.5b 模型并保持运行 ollama run qwen2.5:1.5b > /dev/null 2>&1 & CHAT_PID=$! # 等待模型加载完成 echo "Waiting for models to load into memory..." sleep 15 # 验证模型是否可用 echo "Checking available models..." curl -s http://localhost:11434/api/tags # 4. 启动 FastAPI 接口 echo "Starting FastAPI server..." exec uvicorn app:app --host 0.0.0.0 --port 7860 ``` ### 3.3 app.py(透传版) ```python # app.py import requests from fastapi import FastAPI, Request, Response from fastapi.middleware.cors import CORSMiddleware OLLAMA_BASE_URL = "http://localhost:11434" app = FastAPI(title="Ollama-raw-proxy") # 可选:解决浏览器跨域 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) @app.post("/api/{endpoint}") async def proxy_ollama_dynamic(endpoint: str, raw: Request): """ 动态转发请求到 Ollama API 例如: /api/chat → http://localhost:11434/api/chat /api/generate → http://localhost:11434/api/generate /api/embed → http://localhost:11434/api/embed """ # 构建目标 URL target_url = f"{OLLAMA_BASE_URL}/api/{endpoint}" body = await raw.body() # bytes,保持原样 headers = {"Content-Type": "application/json"} # 转发请求到对应的 Ollama API r = requests.post(target_url, data=body, headers=headers, timeout=60) return Response(content=r.content, status_code=r.status_code, headers=r.headers) # 保持向后兼容的别名路由 @app.post("/chat") async def proxy_ollama_chat(raw: Request): """向后兼容:/chat → /api/chat""" return await proxy_ollama_dynamic("chat", raw) @app.post("/embed") async def proxy_ollama_embed(raw: Request): """向后兼容:/embed → /api/embed""" return await proxy_ollama_dynamic("embed", raw) @app.get("/") def root(): return {"message": "Ollama raw proxy is running"} ``` ### 3.4 requirements.txt ``` fastapi uvicorn[standard] requests ``` --- ## 4 推送并部署 ```bash git add . git commit -m "feat: ollama qwen3 1.7b on HF Spaces" git push origin main ``` Space 页面会实时刷构建日志,看到 `Ollama is running` 说明容器已就绪。 --- ## 5 快速测试 ### 5.1 查看模型列表 ```bash curl https://<你的-space>.hf.space/api/tags ``` ### 5.2 生成文本 ```bash curl https://<你的-space>.hf.space/generate \ -H "Content-Type: application/json" \ -d '{"model":"qwen2.5:1.5b","prompt":"天空为什么是蓝色的?","stream":false}' ``` 返回示例 ```json {"model":"qwen2.5:1.5b","response":"天空呈现蓝色是由于瑞利散射现象……","done":true} ``` ### 5.3 Python 客户端 ```python import requests url = "https://<你的-space>.hf.space/generate" payload = { "model": "qwen2.5:1.5b", "prompt": "用三句话介绍量子计算", "stream": False } print(requests.post(url, json=payload).json()["response"]) ``` --- ## 6 常见问题速查 | 现象 | 解决 | |---|---| | curl: command not found | Dockerfile 里 `apt install curl` | | externally-managed-environment | 用 python3-venv 或 `--break-system-packages` | | 502/504 | 模型尚未拉完,看日志等 1-2 分钟 | | 想跑 7B+ | Spaces 硬件切到 GPU(收费)再拉 `qwen3:7b` | --- ## 7 进阶玩法 1. 换模型:把 `entrypoint.sh` 里的 `ollama pull qwen2.5:1.5b` 改成 `gemma3:1b`、`nomic-embed-text:latest` 等,重新 push 即可。 2. 流式输出:把 `stream=true` 并在客户端逐行读取 `response` 字段。 3. 嵌入模型:用 `/api/embeddings` 端点,见 示例。 --- 至此,你已经拥有了一个**公网可访问、24 h 在线、免费 CPU 运行**的 Ollama 推理节点。 把接口地址填到 ChatBox、Open-WebUI、AnythingLLM 等客户端,就能随时与本地/线上小模型对话啦!

  

🫵 来啊,说点有用的废话!