Spaces:
Running
on
Zero
Running
on
Zero
import re | |
import threading | |
import gradio as gr | |
import spaces | |
import transformers | |
from transformers import pipeline | |
# λͺ¨λΈκ³Ό ν ν¬λμ΄μ λ‘λ© | |
model_name = "CohereForAI/c4ai-command-r7b-arabic-02-2025" | |
if gr.NO_RELOAD: | |
pipe = pipeline( | |
"text-generation", | |
model=model_name, | |
device_map="auto", | |
torch_dtype="auto", | |
) | |
# μ΅μ’ λ΅λ³μ κ°μ§νκΈ° μν λ§μ»€ | |
ANSWER_MARKER = "**λ΅λ³**" | |
# λ¨κ³λ³ μΆλ‘ μ μμνλ λ¬Έμ₯λ€ | |
rethink_prepends = [ | |
"μ, μ΄μ λ€μμ νμ ν΄μΌ ν©λλ€ ", | |
"μ μκ°μλ ", | |
"μ μλ§μ, μ μκ°μλ ", | |
"λ€μ μ¬νμ΄ λ§λμ§ νμΈν΄ λ³΄κ² μ΅λλ€ ", | |
"λν κΈ°μ΅ν΄μΌ ν κ²μ ", | |
"λ λ€λ₯Έ μ£Όλͺ©ν μ μ ", | |
"κ·Έλ¦¬κ³ μ λ λ€μκ³Ό κ°μ μ¬μ€λ κΈ°μ΅ν©λλ€ ", | |
"μ΄μ μΆ©λΆν μ΄ν΄νλ€κ³ μκ°ν©λλ€ ", | |
"μ§κΈκΉμ§μ μ 보λ₯Ό λ°νμΌλ‘, μλ μ§λ¬Έμ μ¬μ©λ μΈμ΄λ‘ λ΅λ³νκ² μ΅λλ€:" | |
"\n{question}\n" | |
f"\n{ANSWER_MARKER}\n", | |
] | |
# μμ νμ λ¬Έμ ν΄κ²°μ μν μ€μ | |
latex_delimiters = [ | |
{"left": "$$", "right": "$$", "display": True}, | |
{"left": "$", "right": "$", "display": False}, | |
] | |
def reformat_math(text): | |
"""Gradio ꡬ문(Katex)μ μ¬μ©νλλ‘ MathJax κ΅¬λΆ κΈ°νΈ μμ . | |
μ΄κ²μ Gradioμμ μν 곡μμ νμνκΈ° μν μμ ν΄κ²°μ± μ λλ€. νμ¬λ‘μλ | |
λ€λ₯Έ latex_delimitersλ₯Ό μ¬μ©νμ¬ μμλλ‘ μλνκ² νλ λ°©λ²μ μ°Ύμ§ λͺ»νμ΅λλ€... | |
""" | |
text = re.sub(r"\\\[\s*(.*?)\s*\\\]", r"$$\1$$", text, flags=re.DOTALL) | |
text = re.sub(r"\\\(\s*(.*?)\s*\\\)", r"$\1$", text, flags=re.DOTALL) | |
return text | |
def user_input(message, history_original, history_thinking): | |
"""μ¬μ©μ μ λ ₯μ νμ€ν 리μ μΆκ°νκ³ μ λ ₯ ν μ€νΈ μμ λΉμ°κΈ°""" | |
return "", history_original + [ | |
gr.ChatMessage(role="user", content=message.replace(ANSWER_MARKER, "")) | |
], history_thinking + [ | |
gr.ChatMessage(role="user", content=message.replace(ANSWER_MARKER, "")) | |
] | |
def rebuild_messages(history: list): | |
"""μ€κ° μκ° κ³Όμ μμ΄ λͺ¨λΈμ΄ μ¬μ©ν νμ€ν 리μμ λ©μμ§ μ¬κ΅¬μ±""" | |
messages = [] | |
for h in history: | |
if isinstance(h, dict) and not h.get("metadata", {}).get("title", False): | |
messages.append(h) | |
elif ( | |
isinstance(h, gr.ChatMessage) | |
and h.metadata.get("title") | |
and isinstance(h.content, str) | |
): | |
messages.append({"role": h.role, "content": h.content}) | |
return messages | |
def bot_original( | |
history: list, | |
max_num_tokens: int, | |
do_sample: bool, | |
temperature: float, | |
): | |
"""μλ³Έ λͺ¨λΈμ΄ μ§λ¬Έμ λ΅λ³νλλ‘ νκΈ° (μΆλ‘ κ³Όμ μμ΄)""" | |
# λμ€μ μ€λ λμμ ν ν°μ μ€νΈλ¦ΌμΌλ‘ κ°μ Έμ€κΈ° μν¨ | |
streamer = transformers.TextIteratorStreamer( | |
pipe.tokenizer, # pyright: ignore | |
skip_special_tokens=True, | |
skip_prompt=True, | |
) | |
# 보쑰μ λ©μμ§ μ€λΉ | |
history.append( | |
gr.ChatMessage( | |
role="assistant", | |
content=str(""), | |
) | |
) | |
# νμ¬ μ±ν μ νμλ λ©μμ§ | |
messages = rebuild_messages(history[:-1]) # λ§μ§λ§ λΉ λ©μμ§ μ μΈ | |
# μλ³Έ λͺ¨λΈμ μΆλ‘ μμ΄ λ°λ‘ λ΅λ³ | |
t = threading.Thread( | |
target=pipe, | |
args=(messages,), | |
kwargs=dict( | |
max_new_tokens=max_num_tokens, | |
streamer=streamer, | |
do_sample=do_sample, | |
temperature=temperature, | |
), | |
) | |
t.start() | |
for token in streamer: | |
history[-1].content += token | |
history[-1].content = reformat_math(history[-1].content) | |
yield history | |
t.join() | |
yield history | |
def bot_thinking( | |
history: list, | |
max_num_tokens: int, | |
final_num_tokens: int, | |
do_sample: bool, | |
temperature: float, | |
): | |
"""μΆλ‘ κ³Όμ μ ν¬ν¨νμ¬ λͺ¨λΈμ΄ μ§λ¬Έμ λ΅λ³νλλ‘ νκΈ°""" | |
# λμ€μ μ€λ λμμ ν ν°μ μ€νΈλ¦ΌμΌλ‘ κ°μ Έμ€κΈ° μν¨ | |
streamer = transformers.TextIteratorStreamer( | |
pipe.tokenizer, # pyright: ignore | |
skip_special_tokens=True, | |
skip_prompt=True, | |
) | |
# νμν κ²½μ° μΆλ‘ μ μ§λ¬Έμ λ€μ μ½μ νκΈ° μν¨ | |
question = history[-1]["content"] | |
# 보쑰μ λ©μμ§ μ€λΉ | |
history.append( | |
gr.ChatMessage( | |
role="assistant", | |
content=str(""), | |
metadata={"title": "π§ μκ° μ€...", "status": "pending"}, | |
) | |
) | |
# νμ¬ μ±ν μ νμλ μΆλ‘ κ³Όμ | |
messages = rebuild_messages(history) | |
for i, prepend in enumerate(rethink_prepends): | |
if i > 0: | |
messages[-1]["content"] += "\n\n" | |
messages[-1]["content"] += prepend.format(question=question) | |
num_tokens = int( | |
max_num_tokens if ANSWER_MARKER not in prepend else final_num_tokens | |
) | |
t = threading.Thread( | |
target=pipe, | |
args=(messages,), | |
kwargs=dict( | |
max_new_tokens=num_tokens, | |
streamer=streamer, | |
do_sample=do_sample, | |
temperature=temperature, | |
), | |
) | |
t.start() | |
# μ λ΄μ©μΌλ‘ νμ€ν 리 μ¬κ΅¬μ± | |
history[-1].content += prepend.format(question=question) | |
if ANSWER_MARKER in prepend: | |
history[-1].metadata = {"title": "π μ¬κ³ κ³Όμ ", "status": "done"} | |
# μκ° μ’ λ£, μ΄μ λ΅λ³μ λλ€ (μ€κ° λ¨κ³μ λν λ©νλ°μ΄ν° μμ) | |
history.append(gr.ChatMessage(role="assistant", content="")) | |
for token in streamer: | |
history[-1].content += token | |
history[-1].content = reformat_math(history[-1].content) | |
yield history | |
t.join() | |
yield history | |
with gr.Blocks(fill_height=True, title="Vidraft ThinkFlow") as demo: | |
# μ λͺ©κ³Ό μ€λͺ | |
gr.Markdown("# Vidraft ThinkFlow") | |
gr.Markdown("### μΆλ‘ κΈ°λ₯μ΄ μλ LLM λͺ¨λΈμ μμ μμ΄λ μΆλ‘ κΈ°λ₯μ μλμΌλ‘ μ μ©νλ LLM μΆλ‘ μμ± νλ«νΌ") | |
# μμ μΉμ | |
with gr.Accordion("EXAMPLES", open=False): | |
gr.Markdown(""" | |
**κ΅κ°μ§ 7κΈ μν λ¬Έμ : λ€μ κΈμ ν΅ν΄ μΆλ‘ ν κ²μΌλ‘ μ μ νμ§ μμ κ²μ?** | |
λ‘컬νΈλ(local food)λ μΌμ°¨μ μΌλ‘ μΌμ ν μ§μμ κΈ°μ€μΌλ‘ ν΄λΉ μ§μμμ μμ°λλ λμνμ μλ―Ένλ€. λ‘컬νΈλλ₯Ό 물리μ 거리λ‘μ¨ κ΅¬μ²΄μ μΌλ‘ κ·μ νλ κ²½μ° μ’κ²λ λ°κ²½ 50 km, λκ²λ λ°κ²½ 100 kmμ λμ΄ μ§μ λ΄μμ μμ°λλ λμνμ μ§μΉνκ³€ νλ€. κ·Έλ λ€κ³ ν΄μ λ‘컬νΈλκ° μ΄ μ λμ 물리μ 거리λ λμ΄μ μ€μ¬μΌλ‘ ν μ§μμ¬νμ λμνμ κ΅νλλ κ²μ μλλ€. μΌλ³Έμ νμ ꡬμμ μ€μ¬μΌλ‘ λ‘컬νΈλλ₯Ό κ·μ νλ κ²½ν₯μ΄ μκ³ , λ―Έκ΅μ κ²½μ° λκ²λ λ°κ²½ 160 km μ λ λ΄μμ μμ°λλ λμνμΌλ‘κΉμ§ νλνκΈ°λ νλ€. μ΄λ μμ°β€μ ν΅β€μλΉμ μμ΄μ 건κ°μ±, μ λ’°μ±, μΉνκ²½μ± λ±μ΄ μ μ§λ μ μλ 거리λ₯Ό κ³ λ €ν κ²μ΄λ€.λ‘컬νΈλκ° μΌμ ν 거리 μ΄λ΄μμ μμ°λ λμνμ μλ―Ένλ κ²μ΄λΌλ©΄, λ‘컬νΈλ μ΄λμ μΉνκ²½μ μ΄κ³ μ립μ μ΄λ©° μ§μ κ°λ₯ν 먹거리λ₯Ό μμ°β€μ ν΅β€μλΉνκ³ μ νλ 곡λ체μ λ Έλ ₯μ μΌμ»«λλ€. λμ μ ν΄μ²΄μ μν μμ μ±μ μκΈ°κ° λ§λλ μ μ μ λ‘컬νΈλ μ΄λμ΄ λ°μνλ λ°°κ²½μ΄ λλ€. μ ν΅μ μΈ λμ μ κ΄λ ¨ μΈκ΅¬ κ°μ, λμ΄ κ²½μ μμΈν, 'μ’ μμμ μνκΉμ§' μ§λ°°νλ κ±°λμλ³Έμ μνμ λ°κ³ μλ€. λμ½μ κ³Όλ€ μ¬μ©μΌλ‘ μΈν΄ μνμ λ¬Όλ‘ μμ°νκ²½μ΄ μκΈ°μ μ²νκ² λμλ€. μ΄λ¬ν λ¬Έμ μ μ λμνκΈ° μν΄ μΉνκ²½ 먹거리 μμ°κ³Ό 건κ°ν μλΉλ₯Ό μ°κ²°νκ³ , λμκ° μ§μ μ 체μ±μ κ°ννλ λ± λμμ 곡λ체 μ΄λμΌλ‘ μ μνμν€λ €λ λ Έλ ₯μ΄ λ‘컬νΈλ μ΄λμΌλ‘ λνλ¬λ€. | |
β λ‘컬νΈλμ λ²μλ κ²½μ μ μμλ₯Ό κ³ λ €ν΄μ κ·μ λ μ μλ€. | |
β‘ μν μμ μ±μ μ£Όλͺ©νλ λ‘컬νΈλ μ΄λμ νκ²½λ³΄νΈ μ΄λκ³Όλ λ°μ ν κ΄λ ¨μ μ§λλ€κ³ λ³Ό μ μλ€. | |
β’ μ§μμ μ 체μ±μ λλ¬λ΄λ νλμ μ λ΅μΌλ‘ ν΄λΉ μ§μμμ μ°μΆλλ λ‘컬νΈλλ₯Ό νμ©ν μ μλ€. | |
β£ μ§μ λκ°κ° κ±°λμλ³Έμ μμ‘΄νμ¬ μμ°κ³Ό μλΉλ₯Ό μ°κ²°νλ €λ μλλ λ‘컬νΈλ μ΄λμ μΌνμΌ μ μλ€. | |
""") | |
with gr.Row(scale=1): | |
with gr.Column(scale=2): | |
gr.Markdown("## Before (Original)") | |
chatbot_original = gr.Chatbot( | |
scale=1, | |
type="messages", | |
latex_delimiters=latex_delimiters, | |
label="Original Model (No Reasoning)" | |
) | |
with gr.Column(scale=2): | |
gr.Markdown("## After (Thinking)") | |
chatbot_thinking = gr.Chatbot( | |
scale=1, | |
type="messages", | |
latex_delimiters=latex_delimiters, | |
label="Model with Reasoning" | |
) | |
with gr.Row(): | |
msg = gr.Textbox( | |
submit_btn=True, | |
label="", | |
show_label=False, | |
placeholder="μ¬κΈ°μ μ§λ¬Έμ μ λ ₯νμΈμ.", | |
autofocus=True, | |
) | |
with gr.Row(): | |
with gr.Column(): | |
gr.Markdown("""## λ§€κ°λ³μ μ‘°μ """) | |
num_tokens = gr.Slider( | |
50, | |
4000, | |
2000, | |
step=1, | |
label="μΆλ‘ λ¨κ³λΉ μ΅λ ν ν° μ", | |
interactive=True, | |
) | |
final_num_tokens = gr.Slider( | |
50, | |
4000, | |
2000, | |
step=1, | |
label="μ΅μ’ λ΅λ³μ μ΅λ ν ν° μ", | |
interactive=True, | |
) | |
do_sample = gr.Checkbox(True, label="μνλ§ μ¬μ©") | |
temperature = gr.Slider(0.1, 1.0, 0.7, step=0.1, label="μ¨λ") | |
# μ¬μ©μκ° λ©μμ§λ₯Ό μ μΆνλ©΄ λ λ΄μ΄ λμμ μλ΅ν©λλ€ | |
msg.submit( | |
user_input, | |
[msg, chatbot_original, chatbot_thinking], # μ λ ₯ | |
[msg, chatbot_original, chatbot_thinking], # μΆλ ₯ | |
).then( | |
bot_original, | |
[ | |
chatbot_original, | |
num_tokens, | |
do_sample, | |
temperature, | |
], | |
chatbot_original, # μΆλ ₯μμ μ νμ€ν 리 μ μ₯ | |
).then( | |
bot_thinking, | |
[ | |
chatbot_thinking, | |
num_tokens, | |
final_num_tokens, | |
do_sample, | |
temperature, | |
], | |
chatbot_thinking, # μΆλ ₯μμ μ νμ€ν 리 μ μ₯ | |
) | |
if __name__ == "__main__": | |
demo.queue().launch() |