初始化项目,由ModelHub XC社区提供模型

Model: ksjpswaroop/zindango-slm
Source: Original Platform
This commit is contained in:
ModelHub XC
2026-06-12 16:07:16 +08:00
commit d2a9610a11
17 changed files with 800 additions and 0 deletions

View File

@@ -0,0 +1,98 @@
#!/usr/bin/env python3
"""
Convert zindango-slm to GGUF and push to Hugging Face.
Requires: llama.cpp cloned, gguf, sentencepiece
pip install gguf sentencepiece
git clone https://github.com/ggml-org/llama.cpp
Usage:
python scripts/convert_and_push_gguf.py [--model-dir PATH] [--quantize Q4_K_M]
"""
import argparse
import subprocess
import sys
from pathlib import Path
from huggingface_hub import HfApi, create_repo, upload_folder, upload_file
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--model-dir", default="outputs/zindango-slm-20260215_124754")
parser.add_argument("--llama-cpp", default="/home/piren/projects/llama.cpp")
parser.add_argument("--quantize", choices=["q4_k_m", "q5_k_m", "q8_0", "none"], default="none")
parser.add_argument("--repo-id", default=None)
parser.add_argument("--skip-create", action="store_true")
parser.add_argument("--push-only", action="store_true", help="Skip conversion, only push existing GGUF")
args = parser.parse_args()
project_root = Path(__file__).resolve().parent.parent
model_dir = project_root / args.model_dir
out_dir = project_root / "outputs"
f16_gguf = out_dir / "zindango-slm-f16.gguf"
if not args.push_only:
llama_cpp = Path(args.llama_cpp)
if not (llama_cpp / "convert_hf_to_gguf.py").exists():
raise SystemExit(f"llama.cpp not found at {llama_cpp}. Clone it first.")
if not model_dir.exists():
raise SystemExit(f"Model not found: {model_dir}")
# Convert to F16 GGUF
cmd = [
sys.executable,
str(llama_cpp / "convert_hf_to_gguf.py"),
str(model_dir),
"--outtype", "f16",
"--outfile", str(f16_gguf),
]
print("Converting to GGUF f16...")
subprocess.run(cmd, check=True)
# Optionally quantize
if args.quantize != "none":
quant_bin = llama_cpp / "build" / "bin" / "llama-quantize"
if not quant_bin.exists():
quant_bin = llama_cpp / "bin" / "llama-quantize"
if quant_bin.exists():
q_gguf = out_dir / f"zindango-slm-{args.quantize}.gguf"
cmd = [str(quant_bin), str(f16_gguf), str(q_gguf), args.quantize.upper()]
print(f"Quantizing to {args.quantize}...")
subprocess.run(cmd, check=True)
else:
print("llama-quantize not found; skipping quantization")
# Push to Hub
api = HfApi()
user = api.whoami()
username = user["name"]
repo_id = args.repo_id or f"{username}/zindango-slm"
if not args.skip_create:
try:
create_repo(repo_id, repo_type="model", exist_ok=True)
except Exception as e:
if "403" in str(e).lower() or "forbidden" in str(e).lower():
print("Create repo failed. Run with --skip-create after creating manually.")
raise
# Upload GGUF file(s): f16 + any quantized (q4_k_m, q8_0, etc.)
quant_ggufs = list(out_dir.glob("zindango-slm-q*.gguf")) + list(out_dir.glob("zindango-slm-Q*.gguf"))
for gguf_path in [f16_gguf] + quant_ggufs:
if gguf_path.exists():
print(f"Uploading {gguf_path.name}...")
upload_file(
path_or_fileobj=str(gguf_path),
path_in_repo=gguf_path.name,
repo_id=repo_id,
repo_type="model",
commit_message=f"Add {gguf_path.name}",
)
print(f"Done. Model: https://huggingface.co/{repo_id}")
if __name__ == "__main__":
main()

105
scripts/llamacpp_chat.py Normal file
View File

@@ -0,0 +1,105 @@
#!/usr/bin/env python3
"""
llama.cpp chat with zindango-slm (GGUF) for English chat verification.
Uses llama-cpp-python with the Q8_0 quantized model from Hugging Face.
"""
import os
import sys
def main():
try:
from llama_cpp import Llama
except ImportError:
print("llama-cpp-python not installed.")
print("Install: pip install llama-cpp-python")
print("Or use pre-built wheels: pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu")
print("For GPU: pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121")
print("\nAlternatively run: ./scripts/llamacpp_chat.sh (requires llama-cli from llama.cpp)")
return 1
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
model_dir = os.path.join(project_root, "models", "zindango-slm")
gguf_path = os.path.join(model_dir, "zindango-slm-Q8_0.gguf")
if not os.path.isfile(gguf_path):
print(f"GGUF not found at {gguf_path}")
print("Download with: huggingface-cli download ksjpswaroop/zindango-slm zindango-slm-Q8_0.gguf --local-dir models/zindango-slm")
os.makedirs(model_dir, exist_ok=True)
try:
from huggingface_hub import hf_hub_download
print("Downloading zindango-slm-Q8_0.gguf from Hugging Face...")
path = hf_hub_download(
repo_id="ksjpswaroop/zindango-slm",
filename="zindango-slm-Q8_0.gguf",
local_dir=model_dir,
local_dir_use_symlinks=False,
)
gguf_path = path
except Exception as e:
print(f"Download failed: {e}")
return 1
print("Loading zindango-slm (Q8_0)...")
llm = Llama(
model_path=gguf_path,
n_ctx=2048,
n_threads=os.cpu_count() or 4,
chat_format="chatml",
verbose=False,
)
messages = [
{"role": "system", "content": "You are a helpful assistant. Always respond in English."},
]
print("\n" + "=" * 60)
print("zindango-slm Chat (llama.cpp) - English verification")
print("=" * 60)
print("Type your message and press Enter. Commands: /quit, /clear")
print()
while True:
try:
user_input = input("You: ").strip()
except (EOFError, KeyboardInterrupt):
print("\nBye!")
break
if not user_input:
continue
if user_input.lower() in ("/quit", "/exit", "quit", "exit"):
print("Bye!")
break
if user_input.lower() == "/clear":
messages = [messages[0]]
print("[Context cleared]")
continue
messages.append({"role": "user", "content": user_input})
print("Assistant: ", end="", flush=True)
stream = llm.create_chat_completion(
messages=messages,
max_tokens=512,
temperature=0.7,
stream=True,
)
full_reply = ""
for chunk in stream:
delta = chunk["choices"][0].get("delta", {})
content = delta.get("content", "")
if content:
print(content, end="", flush=True)
full_reply += content
print()
if full_reply:
messages.append({"role": "assistant", "content": full_reply})
return 0
if __name__ == "__main__":
sys.exit(main())

25
scripts/llamacpp_chat.sh Normal file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
# llama.cpp chat with zindango-slm for English verification
# Prerequisites: llama.cpp built (llama-cli) and GGUF model
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
MODEL_DIR="${MODEL_DIR:-$PROJECT_ROOT/models/zindango-slm}"
GGUF="${GGUF:-$MODEL_DIR/zindango-slm-Q8_0.gguf}"
LLAMA_CLI="${LLAMA_CLI:-llama-cli}"
if ! command -v "$LLAMA_CLI" &>/dev/null; then
echo "llama-cli not found. Build llama.cpp or set LLAMA_CLI:"
echo " git clone https://github.com/ggerganov/llama.cpp && cd llama.cpp && make"
exit 1
fi
if [[ ! -f "$GGUF" ]]; then
echo "GGUF not found. Downloading..."
mkdir -p "$MODEL_DIR"
huggingface-cli download ksjpswaroop/zindango-slm zindango-slm-Q8_0.gguf --local-dir "$MODEL_DIR" || exit 1
fi
echo "=== zindango-slm Chat (llama.cpp) - English verification ==="
exec "$LLAMA_CLI" -m "$GGUF" -c 2048 -i

View File

@@ -0,0 +1,63 @@
#!/usr/bin/env python3
"""
Push zindango-slm scripts to Hugging Face model repo (scripts/ folder).
Usage:
python scripts/push_scripts_to_hub.py [--repo-id USERNAME/zindango-slm]
"""
import argparse
from pathlib import Path
from huggingface_hub import HfApi, create_repo, upload_file
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--repo-id", default=None)
parser.add_argument("--skip-create", action="store_true")
args = parser.parse_args()
sft_root = Path(__file__).resolve().parent.parent
benchmark_root = sft_root.parent / "nanbeige-benchmark-verification"
api = HfApi()
user = api.whoami()
username = user["name"]
repo_id = args.repo_id or f"{username}/zindango-slm"
if not args.skip_create:
try:
create_repo(repo_id, repo_type="model", exist_ok=True)
except Exception as e:
if "403" in str(e).lower() or "forbidden" in str(e).lower():
print("Create repo failed. Run with --skip-create.")
raise
scripts_to_upload = [
(sft_root / "scripts/convert_and_push_gguf.py", "scripts/convert_and_push_gguf.py"),
(sft_root / "scripts/push_to_hub.py", "scripts/push_to_hub.py"),
(sft_root / "scripts/push_scripts_to_hub.py", "scripts/push_scripts_to_hub.py"),
(benchmark_root / "scripts/test_zindango_gguf.py", "scripts/test_zindango_gguf.py"),
(benchmark_root / "scripts/llamacpp_chat.py", "scripts/llamacpp_chat.py"),
(benchmark_root / "scripts/llamacpp_chat.sh", "scripts/llamacpp_chat.sh"),
]
for local_path, path_in_repo in scripts_to_upload:
if not local_path.exists():
print(f"Skipping {local_path} (not found)")
continue
print(f"Uploading {path_in_repo}...")
upload_file(
path_or_fileobj=str(local_path),
path_in_repo=path_in_repo,
repo_id=repo_id,
repo_type="model",
commit_message=f"Add {path_in_repo}",
)
print(f"Done. https://huggingface.co/{repo_id}")
if __name__ == "__main__":
main()

85
scripts/push_to_hub.py Normal file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""
Push zindango-slm to Hugging Face Hub.
Usage:
python scripts/push_to_hub.py [--model-dir PATH] [--repo-id USERNAME/zindango-slm]
Requires: huggingface-cli login (or HF_TOKEN env)
"""
import argparse
from pathlib import Path
from huggingface_hub import HfApi, create_repo, upload_folder
def main():
parser = argparse.ArgumentParser(description="Push zindango-slm to Hugging Face Hub")
parser.add_argument(
"--model-dir",
type=str,
default="outputs/zindango-slm-20260215_124754",
help="Local model directory to upload",
)
parser.add_argument(
"--repo-id",
type=str,
default=None,
help="Hub repo ID (username/zindango-slm). Default: infer from login",
)
parser.add_argument(
"--private",
action="store_true",
help="Create private repository",
)
parser.add_argument(
"--skip-create",
action="store_true",
help="Skip create_repo (use if repo already exists or create manually at https://huggingface.co/new)",
)
args = parser.parse_args()
model_dir = Path(args.model_dir)
if not model_dir.exists():
raise SystemExit(f"Model directory not found: {model_dir}")
api = HfApi()
try:
user = api.whoami()
username = user["name"]
except Exception as e:
raise SystemExit(
f"Not logged in to Hugging Face. Run: huggingface-cli login\nError: {e}"
)
repo_id = args.repo_id or f"{username}/zindango-slm"
print(f"Uploading to https://huggingface.co/{repo_id}")
# Create repo if needed (skip if --skip-create or 403)
if not args.skip_create:
try:
create_repo(repo_id, repo_type="model", private=args.private, exist_ok=True)
except Exception as e:
err = str(e).lower()
if "403" in err or "forbidden" in err or "rights" in err:
print("Note: Could not create repo (check token write access).")
print("Create it manually at: https://huggingface.co/new")
print("Then run with: --skip-create")
raise
if "already exists" not in err and "409" not in err:
raise
# Exclude checkpoint subdir and training artifacts
ignore_patterns = ["checkpoint-*", "training_args.bin", "*.pt", ".git*"]
upload_folder(
folder_path=str(model_dir),
repo_id=repo_id,
repo_type="model",
ignore_patterns=ignore_patterns,
commit_message="Upload zindango-slm: SFT for Zindango (English-only)",
)
print(f"Done. Model: https://huggingface.co/{repo_id}")
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,94 @@
#!/usr/bin/env python3
"""
Test zindango-slm: GGUF (llama-cpp-python) or HF (transformers) fallback.
Runs a single prompt to verify the model loads and generates.
"""
import os
import sys
def test_gguf(gguf_path: str) -> bool:
"""Test via llama-cpp-python if available."""
try:
from llama_cpp import Llama
except ImportError:
return False
print("Loading zindango-slm (GGUF) with llama-cpp-python...")
llm = Llama(
model_path=gguf_path,
n_ctx=512,
n_threads=os.cpu_count() or 4,
chat_format="chatml",
verbose=False,
)
messages = [
{"role": "system", "content": "You are a helpful assistant. Reply briefly."},
{"role": "user", "content": "Who are you? One sentence only."},
]
out = llm.create_chat_completion(messages=messages, max_tokens=64, temperature=0.7)
reply = out["choices"][0]["message"]["content"]
print("Reply:", reply)
return bool(reply.strip())
def test_transformers(local_path: str | None = None) -> bool:
"""Test via transformers (HF model) as fallback when GGUF/llama.cpp unavailable."""
try:
from transformers import AutoModelForCausalLM, AutoTokenizer
except ImportError:
print("transformers not installed: pip install transformers torch")
return False
model_id = local_path if local_path and os.path.isdir(local_path) else "ksjpswaroop/zindango-slm"
print(f"Testing zindango-slm (transformers) - fallback when llama-cpp unavailable...")
tokenizer = AutoTokenizer.from_pretrained(model_id, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
model_id,
trust_remote_code=True,
torch_dtype="auto",
low_cpu_mem_usage=True,
)
messages = [{"role": "user", "content": "Who are you? One sentence only."}]
text = tokenizer.apply_chat_template(
messages, tokenize=False, add_generation_prompt=True
)
inputs = tokenizer(text, return_tensors="pt")
out = model.generate(
**inputs, max_new_tokens=64, pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id
)
reply = tokenizer.decode(
out[0][inputs["input_ids"].shape[1] :], skip_special_tokens=True
)
print("Reply:", reply)
return bool(reply.strip())
def main():
script_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(script_dir)
model_dir = os.path.join(project_root, "models", "zindango-slm")
# Prefer Q8_0, then f16
for name in ("zindango-slm-Q8_0.gguf", "zindango-slm-f16.gguf"):
gguf_path = os.path.join(model_dir, name)
if os.path.isfile(gguf_path):
print(f"Trying GGUF: {gguf_path}")
if test_gguf(gguf_path):
print("\n[OK] zindango-slm GGUF test passed.")
return 0
break
print("\nllama-cpp-python unavailable or failed. Using transformers fallback...")
local_hf = os.path.join(project_root, "models", "zindango-slm-hf")
if test_transformers(local_hf):
print("\n[OK] zindango-slm transformers test passed.")
return 0
print("\n[FAIL] No working backend. Install: pip install transformers torch")
print("For GGUF: pip install llama-cpp-python")
return 1
if __name__ == "__main__":
sys.exit(main())