File size: 4,455 Bytes
8c029ff
 
1284be2
625f637
8c029ff
1284be2
8c029ff
1284be2
 
8c029ff
 
1284be2
8c029ff
1284be2
 
8c029ff
1284be2
 
8c029ff
1284be2
075fe02
1284be2
 
625f637
1284be2
 
8c029ff
 
1284be2
 
8c029ff
 
1284be2
8c029ff
 
 
075fe02
1284be2
8c029ff
 
 
 
1284be2
 
075fe02
1284be2
 
 
 
 
 
 
 
 
 
8c029ff
 
1284be2
 
8c029ff
1284be2
8c029ff
 
1284be2
8c029ff
 
 
 
 
 
 
 
 
1284be2
 
 
 
8c029ff
1284be2
8c029ff
 
 
 
1284be2
075fe02
8c029ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3c5913d
075fe02
 
1284be2
075fe02
8c029ff
 
 
1284be2
8c029ff
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import os
import torch
import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer

# وصف التطبيق
DESCRIPTION = """\
# Llama 3.2 3B Instruct (CPU-Only)
هذا نموذج توضيحي لـ [`meta-llama/Llama-3.2-3B-Instruct`](https://huggingface.co/meta-llama/Llama-3.2-3B-Instruct) يعمل باستخدام الـ CPU فقط.
"""

# إعداد الثوابت
MAX_MAX_NEW_TOKENS = 2048
DEFAULT_MAX_NEW_TOKENS = 512
MAX_INPUT_TOKEN_LENGTH = 4096  # الحد الأقصى لعدد التوكنات في المدخلات

# تحديد الجهاز: استخدام CPU فقط
device = torch.device("cpu")

# تحديد معرف النموذج وتحميله
model_id = "meta-llama/Llama-3.2-3B-Instruct"

# تحميل التوكن الخاص بالنموذج
tokenizer = AutoTokenizer.from_pretrained(model_id)

# تحميل النموذج على CPU مع استخدام torch.float32
model = AutoModelForCausalLM.from_pretrained(
    model_id,
    device_map=None,         # عدم استخدام GPU
    torch_dtype=torch.float32
)
model.eval()
model.to(device)

def generate(
    message: str,
    chat_history: list[dict],
    max_new_tokens: int = DEFAULT_MAX_NEW_TOKENS,
    temperature: float = 0.6,
    top_p: float = 0.9,
    top_k: int = 50,
    repetition_penalty: float = 1.2,
):
    # دمج سجل المحادثة مع الرسالة الجديدة
    conversation = [*chat_history, {"role": "user", "content": message}]
    
    # تحويل المحادثة إلى مدخلات للنموذج
    inputs = tokenizer.apply_chat_template(
        conversation, 
        add_generation_prompt=True, 
        return_tensors="pt"
    )
    input_ids = inputs["input_ids"]
    
    # قص التوكنز إذا تجاوز طولها الحد المسموح
    if input_ids.shape[1] > MAX_INPUT_TOKEN_LENGTH:
        input_ids = input_ids[:, -MAX_INPUT_TOKEN_LENGTH:]
    
    input_ids = input_ids.to(device)

    # إعداد البث التدريجي للنص باستخدام TextIteratorStreamer
    streamer = TextIteratorStreamer(tokenizer, timeout=20.0, skip_prompt=True, skip_special_tokens=True)
    generate_kwargs = dict(
        input_ids=input_ids,
        streamer=streamer,
        max_new_tokens=max_new_tokens,
        do_sample=True,
        top_p=top_p,
        top_k=top_k,
        temperature=temperature,
        num_beams=1,
        repetition_penalty=repetition_penalty,
    )
    
    # تشغيل عملية التوليد على نفس الخيط (CPU)
    model.generate(**generate_kwargs)
    
    outputs = []
    # بث النص تدريجيًا أثناء توليد النموذج
    for text in streamer:
        outputs.append(text)
        yield "".join(outputs)

# إنشاء واجهة الدردشة باستخدام Gradio
demo = gr.ChatInterface(
    fn=generate,
    additional_inputs=[
        gr.Slider(
            label="Max new tokens",
            minimum=1,
            maximum=MAX_MAX_NEW_TOKENS,
            step=1,
            value=DEFAULT_MAX_NEW_TOKENS,
        ),
        gr.Slider(
            label="Temperature",
            minimum=0.1,
            maximum=4.0,
            step=0.1,
            value=0.6,
        ),
        gr.Slider(
            label="Top-p (nucleus sampling)",
            minimum=0.05,
            maximum=1.0,
            step=0.05,
            value=0.9,
        ),
        gr.Slider(
            label="Top-k",
            minimum=1,
            maximum=1000,
            step=1,
            value=50,
        ),
        gr.Slider(
            label="Repetition penalty",
            minimum=1.0,
            maximum=2.0,
            step=0.05,
            value=1.2,
        ),
    ],
    stop_btn=None,
    examples=[
        ["Hello there! How are you doing?"],
        ["Can you explain briefly to me what is the Python programming language?"],
        ["Explain the plot of Cinderella in a sentence."],
        ["How many hours does it take a man to eat a Helicopter?"],
        ["Write a 100-word article on 'Benefits of Open-Source in AI research'"],
    ],
    cache_examples=False,
    type="messages",
    description=DESCRIPTION,
    css_paths="style.css",   # تأكدي من رفع ملف style.css إذا كان موجوداً
    fill_height=True,
)

if __name__ == "__main__":
    # استخدام queue() لإدارة الطلبات المتزامنة
    demo.queue(max_size=20).launch()