ibrahimlasfar commited on
Commit
625c5f1
·
1 Parent(s): bc187ec

Fix and add entrypoint.sh

Browse files
Files changed (4) hide show
  1. Dockerfile +20 -13
  2. app.py +15 -22
  3. entrypoint.sh +10 -0
  4. setup.sh +7 -4
Dockerfile CHANGED
@@ -1,25 +1,32 @@
 
 
 
1
  FROM python:3.10-slim
2
 
3
- # تثبيت المتطلبات الأساسية
4
- RUN apt-get update && apt-get install -y git wget && rm -rf /var/lib/apt/lists/*
 
 
5
 
6
- # إعداد مجلد العمل
7
  WORKDIR /app
8
 
9
- # نسخ ملفات التطبيق
10
  COPY requirements.txt .
11
- RUN pip install --no-cache-dir -r requirements.txt
 
 
12
 
13
- # نسخ السكريبتات والملفات
14
  COPY app.py .
15
  COPY setup.sh .
16
- RUN chmod +x setup.sh
 
17
 
18
- # تحميل النموذج
19
- RUN ./setup.sh
20
-
21
- # تعيين المتغيّر لتجنب التحذير
22
  ENV HF_HOME=/root/.cache/huggingface
 
 
23
 
24
- # تشغيل التطبيق
25
- CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8080"]
 
1
+ # -------------------------------------------------
2
+ # Dockerfile – Python 3.10‑slim + build tools
3
+ # -------------------------------------------------
4
  FROM python:3.10-slim
5
 
6
+ # تثبيت الأدوات الأساسية + git & wget
7
+ RUN apt-get update && \
8
+ apt-get install -y git wget build-essential && \
9
+ rm -rf /var/lib/apt/lists/*
10
 
11
+ # مجلد العمل داخل الحاوية
12
  WORKDIR /app
13
 
14
+ # ---------- المتطلبات ----------
15
  COPY requirements.txt .
16
+ # تحديث pip ثم تثبيت الحزم
17
+ RUN pip install --upgrade pip && \
18
+ pip install --no-cache-dir -r requirements.txt
19
 
20
+ # ---------- الكود ----------
21
  COPY app.py .
22
  COPY setup.sh .
23
+ COPY entrypoint.sh .
24
+ RUN chmod +x setup.sh entrypoint.sh
25
 
26
+ # ---------- إعدادات الـ cache ----------
 
 
 
27
  ENV HF_HOME=/root/.cache/huggingface
28
+ ENV TRANSFORMERS_CACHE=${HF_HOME}
29
+ ENV HF_HUB_CACHE=${HF_HOME}
30
 
31
+ # ---------- نقطة الدخول ----------
32
+ ENTRYPOINT ["./entrypoint.sh"]
app.py CHANGED
@@ -5,14 +5,11 @@ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
5
  from llama_cpp import Llama
6
 
7
  # -------------------------------------------------
8
- # إعداد مسار الـ cache (فقط إذا لم يكن معرفًا سلفًا)
9
  # -------------------------------------------------
10
- CACHE_DIR = "/app/.cache" # نفس المسار الذي عرّفته في Dockerfile
11
  os.makedirs(CACHE_DIR, exist_ok=True)
12
-
13
- # تأكد من أن المكتبتين تقرأ المتغيّرات البيئية
14
  os.environ.setdefault("TRANSFORMERS_CACHE", CACHE_DIR)
15
- os.environ.setdefault("HF_HOME", CACHE_DIR)
16
 
17
  # -------------------------------------------------
18
  # إنشاء التطبيق
@@ -25,54 +22,50 @@ app = FastAPI(
25
  # -------------------------------------------------
26
  # 1️⃣ تحميل نموذج T5 المدرب من Hub
27
  # -------------------------------------------------
28
- T5_REPO = "MGZON/mgzon-flan-t5-base" # إذا رفعت النموذج إلى مستودع آخر غير هذا غير الاسم
29
- t5_tokenizer = AutoTokenizer.from_pretrained(T5_REPO)
30
- t5_model = AutoModelForSeq2SeqLM.from_pretrained(T5_REPO)
31
 
32
  # -------------------------------------------------
33
- # 2️⃣ تحميل ملف Mistral .gguf (تم تنزيله بواسطة setup.sh)
34
  # -------------------------------------------------
35
- gguf_path = os.path.abspath("models/mistral-7b-instruct-v0.1.Q4_K_M.gguf")
36
  if not os.path.exists(gguf_path):
37
- # في حالة عدم وجود الملف (مثلاً إذا لم يُنفّذ setup.sh) نُظهر رسالة واضحة
38
  raise RuntimeError(
39
  f"ملف Mistral .gguf غير موجود في {gguf_path}. "
40
- "تأكد من أن ملف setup.sh تم تنفيذه أثناء الـ build."
41
  )
42
 
43
  mistral = Llama(
44
  model_path=gguf_path,
45
  n_ctx=2048,
46
- n_threads=8, # عدد الـ threads المتاح داخل Space (CPU فقط)
47
  # إذا كان لديك GPU داخل Space يمكنك إضافة n_gpu_layers=35
48
  )
49
 
50
  # -------------------------------------------------
51
- # تعريف شكل الطلب (JSON)
52
  # -------------------------------------------------
53
  class AskRequest(BaseModel):
54
  question: str
55
- max_new_tokens: int = 150 # عدد الكلمات التي تريد استخراجها (يمكن تعديلها)
56
 
57
- # -------------------------------------------------
58
- # نقطة النهاية /ask
59
- # -------------------------------------------------
60
  @app.post("/ask")
61
  def ask(req: AskRequest):
62
  q = req.question.strip()
63
  if not q:
64
  raise HTTPException(status_code=400, detail="Empty question")
65
 
66
- # منطق بسيط لاختيار النموذج:
67
- # إذا احتوى السؤال على كلمة مفتاحية نستخدم T5، وإلا نستخدم Mistral
68
  if any(tok in q.lower() for tok in ["mgzon", "flan", "t5"]):
69
- # --------- نموذج T5 ----------
70
  inputs = t5_tokenizer(q, return_tensors="pt", truncation=True, max_length=256)
71
  out_ids = t5_model.generate(**inputs, max_length=req.max_new_tokens)
72
  answer = t5_tokenizer.decode(out_ids[0], skip_special_tokens=True)
73
  model_name = "MGZON‑FLAN‑T5"
74
  else:
75
- # --------- نموذج Mistral ----------
76
  out = mistral(prompt=q, max_tokens=req.max_new_tokens)
77
  answer = out["choices"][0]["text"].strip()
78
  model_name = "Mistral‑7B‑GGUF"
 
5
  from llama_cpp import Llama
6
 
7
  # -------------------------------------------------
8
+ # إعداد مسار الـ cache (يُستَخدم للـ transformers & huggingface)
9
  # -------------------------------------------------
10
+ CACHE_DIR = os.getenv("HF_HOME", "/root/.cache/huggingface")
11
  os.makedirs(CACHE_DIR, exist_ok=True)
 
 
12
  os.environ.setdefault("TRANSFORMERS_CACHE", CACHE_DIR)
 
13
 
14
  # -------------------------------------------------
15
  # إنشاء التطبيق
 
22
  # -------------------------------------------------
23
  # 1️⃣ تحميل نموذج T5 المدرب من Hub
24
  # -------------------------------------------------
25
+ T5_REPO = "MGZON/mgzon-flan-t5-base"
26
+ t5_tokenizer = AutoTokenizer.from_pretrained(T5_REPO, cache_dir=CACHE_DIR)
27
+ t5_model = AutoModelForSeq2SeqLM.from_pretrained(T5_REPO, cache_dir=CACHE_DIR)
28
 
29
  # -------------------------------------------------
30
+ # 2️⃣ تحميل ملف Mistral .gguf (قد تم تنزيله runtime)
31
  # -------------------------------------------------
32
+ gguf_path = os.path.abspath(os.path.join("models", "mistral-7b-instruct-v0.1.Q4_K_M.gguf"))
33
  if not os.path.exists(gguf_path):
34
+ # إذا لم يُحمَّل (مثلاً بسبب حذف الـ volume) نُعيد تحميله الآن
35
  raise RuntimeError(
36
  f"ملف Mistral .gguf غير موجود في {gguf_path}. "
37
+ "تأكد من أن ملف setup.sh تم تنفيذه (يتم تشغيله تلقائيًا عند بدء الحاوية)."
38
  )
39
 
40
  mistral = Llama(
41
  model_path=gguf_path,
42
  n_ctx=2048,
43
+ n_threads=8,
44
  # إذا كان لديك GPU داخل Space يمكنك إضافة n_gpu_layers=35
45
  )
46
 
47
  # -------------------------------------------------
48
+ # طلبات الـ API
49
  # -------------------------------------------------
50
  class AskRequest(BaseModel):
51
  question: str
52
+ max_new_tokens: int = 150
53
 
 
 
 
54
  @app.post("/ask")
55
  def ask(req: AskRequest):
56
  q = req.question.strip()
57
  if not q:
58
  raise HTTPException(status_code=400, detail="Empty question")
59
 
60
+ # اختيار النموذج بناءً على الكلمات المفتاحية
 
61
  if any(tok in q.lower() for tok in ["mgzon", "flan", "t5"]):
62
+ # ---------- نموذج T5 ----------
63
  inputs = t5_tokenizer(q, return_tensors="pt", truncation=True, max_length=256)
64
  out_ids = t5_model.generate(**inputs, max_length=req.max_new_tokens)
65
  answer = t5_tokenizer.decode(out_ids[0], skip_special_tokens=True)
66
  model_name = "MGZON‑FLAN‑T5"
67
  else:
68
+ # ---------- نموذج Mistral ----------
69
  out = mistral(prompt=q, max_tokens=req.max_new_tokens)
70
  answer = out["choices"][0]["text"].strip()
71
  model_name = "Mistral‑7B‑GGUF"
entrypoint.sh ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ # 1️⃣ تحميل ملف الـ .gguf إذا لم يكن موجودًا
5
+ echo "🔧 تشغيل setup.sh لتحميل النموذج (إن لم يكن موجودًا)..."
6
+ ./setup.sh
7
+
8
+ # 2️⃣ تشغيل الخادم
9
+ echo "🚀 تشغيل Uvicorn ..."
10
+ exec uvicorn app:app --host 0.0.0.0 --port 8080
setup.sh CHANGED
@@ -1,10 +1,10 @@
1
  #!/usr/bin/env bash
2
  set -e
3
 
4
- # 1️⃣ إنشاء مجلد لتخزين النموذج
5
  mkdir -p models
6
 
7
- # 2️⃣ تحميل ملف .gguf إذا لم يكن موجودًا مسبقًا
8
  python - <<PY
9
  from huggingface_hub import hf_hub_download
10
  import os
@@ -13,13 +13,16 @@ repo_id = "TheBloke/Mistral-7B-Instruct-v0.1-GGUF"
13
  filename = "mistral-7b-instruct-v0.1.Q4_K_M.gguf"
14
  local_dir = "models"
15
 
16
- if not os.path.exists(os.path.join(local_dir, filename)):
 
 
 
17
  hf_hub_download(
18
  repo_id=repo_id,
19
  filename=filename,
20
  local_dir=local_dir,
21
  local_dir_use_symlinks=False,
22
- force_download=False
23
  )
24
  print("✅ تم تحميل Mistral .gguf")
25
  else:
 
1
  #!/usr/bin/env bash
2
  set -e
3
 
4
+ # إنشاء مجلد للنماذج
5
  mkdir -p models
6
 
7
+ # تحميل ملف .gguf إذا لم يكن موجودًا مسبقًا
8
  python - <<PY
9
  from huggingface_hub import hf_hub_download
10
  import os
 
13
  filename = "mistral-7b-instruct-v0.1.Q4_K_M.gguf"
14
  local_dir = "models"
15
 
16
+ dest_path = os.path.join(local_dir, filename)
17
+
18
+ if not os.path.exists(dest_path):
19
+ # المتغيّر السري HF_TOKEN يُستَخدم تلقائيًا داخل huggingface_hub
20
  hf_hub_download(
21
  repo_id=repo_id,
22
  filename=filename,
23
  local_dir=local_dir,
24
  local_dir_use_symlinks=False,
25
+ force_download=False,
26
  )
27
  print("✅ تم تحميل Mistral .gguf")
28
  else: