File size: 4,793 Bytes
b754521
f1b8f61
b754521
f1b8f61
b754521
 
 
f1b8f61
 
 
b754521
 
 
 
 
 
 
f1b8f61
b754521
 
 
 
 
 
f1b8f61
b754521
 
 
 
f1b8f61
b754521
f1b8f61
 
 
 
 
b754521
f1b8f61
12b2f89
f1b8f61
 
 
b754521
f1b8f61
 
12b2f89
f1b8f61
b754521
f1b8f61
b754521
 
 
 
 
 
 
f1b8f61
b754521
 
 
 
 
 
 
f1b8f61
12b2f89
 
 
f1b8f61
 
 
 
b754521
f1b8f61
 
 
12b2f89
 
 
f1b8f61
b754521
 
 
f1b8f61
 
12b2f89
 
f1b8f61
 
 
 
 
12b2f89
 
f1b8f61
 
 
 
 
 
 
b754521
f1b8f61
 
 
 
 
12b2f89
f1b8f61
12b2f89
f1b8f61
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# -*- coding: utf-8 -*-
"""samai-4b Colab 一键引导 v2 — 聊天页(7861) + OpenAI兼容API(7862) 双服务.

用法: 在新 Colab (T4 GPU) 笔记本第一个 cell 运行:
    !wget -qO /content/boot.py https://huggingface.co/tchbcb/samai-4b/resolve/main/bootstrap.py
    !python3 /content/boot.py

流程: 装依赖 -> 从 HF 拉 chat_server.py / openai_api.py -> 下载模型 (~8.3GB) ->
启动两个服务 -> 启动两个 aitun 隧道 -> 打印公网地址.
API key: 1234 (Bearer)
"""
import os
import subprocess
import time

T0 = time.time()
REPO = "tchbcb/samai-4b"  # 公开仓库, 匿名下载即可
API_KEY = "1234"


def log(m):
    print(f"[{time.time()-T0:6.1f}s] {m}", flush=True)


def sh(c, t=600):
    r = subprocess.run(c, shell=True, capture_output=True, text=True, timeout=t)
    return (r.stdout + r.stderr).strip()


log("install deps (flask/aitun/transformers==5.16.1) ...")
print(sh("pip install -q flask aitun huggingface_hub 2>&1 | tail -1"))
v = sh("python3 -c 'import transformers;print(transformers.__version__)'")
log(f"transformers = {v}")
if v and not v.startswith("5.16"):
    print(sh("pip install -q transformers==5.16.1 2>&1 | tail -1"))
    log("pinned transformers==5.16.1 (modeling 代码按此版本修补)")

log("pull servers from HF ...")
for f in ["chat_server.py", "openai_api.py", "control_server.py"]:
    subprocess.run(
        f"curl -sL https://huggingface.co/{REPO}/resolve/main/{f} -o /content/{f}",
        shell=True, check=True)
import py_compile  # noqa: E402
py_compile.compile("/content/chat_server.py", doraise=True)
py_compile.compile("/content/openai_api.py", doraise=True)
py_compile.compile("/content/control_server.py", doraise=True)
log("server scripts OK")

log("download model (~8.3GB, 首次约3-6分钟) ...")
r = subprocess.run(
    ["python3", "-c", f"""
from huggingface_hub import snapshot_download
p = snapshot_download("{REPO}",
                      allow_patterns=["*.json","*.py","*.jinja","*.txt","*.safetensors","*.md"])
print("MODEL_DIR:", p)
"""], capture_output=True, text=True)
print(r.stdout[-400:], r.stderr[-300:] if r.returncode else "")
model_dir = [l.split("MODEL_DIR: ")[1].strip() for l in r.stdout.splitlines()
             if "MODEL_DIR:" in l][-1]

if not os.path.exists("/content/samai-4b-sft"):
    os.symlink(model_dir, "/content/samai-4b-sft")
log("model ready: " + model_dir)

subprocess.run("pkill -f chat_server.py; pkill -f openai_api.py; "
               "pkill -f control_server.py; "
               "pkill -f 'aitun -p 7861'; pkill -f 'aitun -p 7862'; "
               "pkill -f 'aitun -p 5000'", shell=True)
time.sleep(2)
env = f"S4_MODEL_DIR=/content/samai-4b-sft S4_API_KEY={API_KEY}"
subprocess.Popen(f"setsid nohup env {env} python3 /content/chat_server.py"
                 f" > /content/chat_run.log 2>&1 &",
                 shell=True, start_new_session=True)
subprocess.Popen(f"setsid nohup env {env} python3 /content/openai_api.py"
                 f" > /content/api_run.log 2>&1 &",
                 shell=True, start_new_session=True)
subprocess.Popen("setsid nohup python3 /content/control_server.py"
                 " > /content/control_run.log 2>&1 &",
                 shell=True, start_new_session=True)
log("services starting (模型加载约2分钟) ...")

subprocess.Popen("setsid nohup aitun -p 7861 > /content/aitun7861.log 2>&1 &",
                 shell=True, start_new_session=True)
subprocess.Popen("setsid nohup aitun -p 7862 > /content/aitun7862.log 2>&1 &",
                 shell=True, start_new_session=True)
subprocess.Popen("setsid nohup aitun -p 5000 > /content/aitun5000.log 2>&1 &",
                 shell=True, start_new_session=True)
time.sleep(12)
log("=== 隧道 7861 (聊天页) ===")
print(sh("tail -4 /content/aitun7861.log"))
log("=== 隧道 7862 (OpenAI API) ===")
print(sh("tail -4 /content/aitun7862.log"))
log("=== 隧道 5000 (远程控制) ===")
print(sh("tail -4 /content/aitun5000.log"))

for name, port in [("chat", 7861), ("api", 7862)]:
    for i in range(30):
        time.sleep(10)
        h = sh(f"curl -s -m 5 http://127.0.0.1:{port}/health", t=10)
        if h and '"loaded": true' in h:
            log(f"[{name}] ready: {h}")
            break
        if i == 29:
            log(f"[{name}] WARN 未就绪: {h}")

log("=" * 60)
log("BOOTSTRAP_DONE")
log(f"聊天页 (UI)       : 见 aitun7861.log 的公网地址")
log(f"OpenAI 兼容 API : 见 aitun7862.log 的公网地址  (key={API_KEY})")
log(f"远程控制通道     : 见 aitun5000.log 的公网地址 (把三个地址都发给助手)")
log("API 测试: curl <API地址>/v1/chat/completions -H 'Authorization: Bearer 1234' "
    "-H 'Content-Type: application/json' "
    "-d '{\"model\":\"samai-4b\",\"messages\":[{\"role\":\"user\",\"content\":\"你好\"}]}'")