openfree commited on
Commit
6432bca
Β·
verified Β·
1 Parent(s): bd6c663

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +110 -0
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datasets import load_dataset
2
+ import gradio as gr
3
+ from gradio_client import Client
4
+ import json
5
+ import torch
6
+ from diffusers import FluxPipeline, AutoencoderKL
7
+ from live_preview_helpers import flux_pipe_call_that_returns_an_iterable_of_images
8
+ import spaces
9
+
10
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
11
+
12
+ pipe = FluxPipeline.from_pretrained("black-forest-labs/FLUX.1-dev", torch_dtype=torch.bfloat16).to(device)
13
+ good_vae = AutoencoderKL.from_pretrained("black-forest-labs/FLUX.1-dev", subfolder="vae", torch_dtype=torch.bfloat16).to(device)
14
+ pipe.flux_pipe_call_that_returns_an_iterable_of_images = flux_pipe_call_that_returns_an_iterable_of_images.__get__(pipe)
15
+
16
+ llm_client = Client("CohereForAI/c4ai-command-r-plus-08-2024")
17
+
18
+ ds = load_dataset("MohamedRashad/FinePersonas-Lite", split="train")
19
+
20
+ prompt_template = """λ‹€μŒ 페λ₯΄μ†Œλ‚˜ μ„€λͺ…을 가진 캐릭터λ₯Ό μƒμ„±ν•˜μ„Έμš”: {persona_description}
21
+ λ‹€μŒ μ„€λͺ…μ˜ μ„Έκ³„μ—μ„œ: {world_description}
22
+ λ‹€μŒ ν•„λ“œλ₯Ό ν¬ν•¨ν•˜λŠ” JSON ν˜•μ‹μœΌλ‘œ 캐릭터λ₯Ό μž‘μ„±ν•˜μ„Έμš”:
23
+ - name: μΊλ¦­ν„°μ˜ 이름
24
+ - background: μΊλ¦­ν„°μ˜ λ°°κ²½
25
+ - appearance: μΊλ¦­ν„°μ˜ μ™Έλͺ¨
26
+ - personality: μΊλ¦­ν„°μ˜ 성격
27
+ - skills_and_abilities: μΊλ¦­ν„°μ˜ 기술과 λŠ₯λ ₯
28
+ - goals: μΊλ¦­ν„°μ˜ λͺ©ν‘œ
29
+ - conflicts: μΊλ¦­ν„°μ˜ κ°ˆλ“±
30
+ - backstory: μΊλ¦­ν„°μ˜ κ³Όκ±° 이야기
31
+ - current_situation: μΊλ¦­ν„°μ˜ ν˜„μž¬ 상황
32
+ - spoken_lines: μΊλ¦­ν„°μ˜ λŒ€μ‚¬ (λ¬Έμžμ—΄ 리슀트)
33
+ JSON ν˜•μ‹μ˜ 캐릭터 μ„€λͺ…λ§Œ μž‘μ„±ν•˜κ³  λ‹€λ₯Έ λ‚΄μš©μ€ ν¬ν•¨ν•˜μ§€ λ§ˆμ„Έμš”. '```'도 ν¬ν•¨ν•˜μ§€ λ§ˆμ„Έμš”.
34
+ """
35
+
36
+ world_description_prompt = "λ…νŠΉν•˜κ³  λ¬΄μž‘μœ„ν•œ 세계 μ„€λͺ…을 μƒμ„±ν•˜μ„Έμš” (세계 μ„€λͺ…λ§Œ μž‘μ„±ν•˜κ³  λ‹€λ₯Έ λ‚΄μš©μ€ ν¬ν•¨ν•˜μ§€ λ§ˆμ„Έμš”)."
37
+
38
+ def get_random_world_description():
39
+ result = llm_client.predict(
40
+ query=world_description_prompt,
41
+ history=[],
42
+ system="당신은 μ•Œλ¦¬λ°”λ°” ν΄λΌμš°λ“œκ°€ λ§Œλ“  Qwenμž…λ‹ˆλ‹€. 당신은 도움이 λ˜λŠ” μ–΄μ‹œμŠ€ν„΄νŠΈμž…λ‹ˆλ‹€.",
43
+ api_name="/model_chat",
44
+ )
45
+ return result[1][0][-1]
46
+
47
+ def get_random_persona_description():
48
+ return ds.shuffle().select([100])[0]["persona"]
49
+
50
+ @spaces.GPU(duration=75)
51
+ def infer_flux(character_json):
52
+ for image in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
53
+ prompt=character_json["appearance"],
54
+ guidance_scale=3.5,
55
+ num_inference_steps=28,
56
+ width=1024,
57
+ height=1024,
58
+ generator=torch.Generator("cpu").manual_seed(0),
59
+ output_type="pil",
60
+ good_vae=good_vae,
61
+ ):
62
+ yield image
63
+
64
+ def generate_character(world_description, persona_description, progress=gr.Progress(track_tqdm=True)):
65
+ result = llm_client.predict(
66
+ query=prompt_template.format(
67
+ persona_description=persona_description, world_description=world_description
68
+ ),
69
+ history=[],
70
+ system="당신은 μ•Œλ¦¬λ°”λ°” ν΄λΌμš°λ“œκ°€ λ§Œλ“  Qwenμž…λ‹ˆλ‹€. 당신은 도움이 λ˜λŠ” μ–΄μ‹œμŠ€ν„΄νŠΈμž…λ‹ˆλ‹€.",
71
+ api_name="/model_chat",
72
+ )
73
+ output = json.loads(result[1][0][-1])
74
+ return output
75
+
76
+ with gr.Blocks(title="캐릭터 μžλ™ 생성", theme="Nymbo/Nymbo_Theme") as app:
77
+ with gr.Column():
78
+ gr.HTML("<center><h1>캐릭터 생성기</h1></center>")
79
+ with gr.Column():
80
+ with gr.Row():
81
+ world_description = gr.Textbox(lines=10, label="세계 μ„€λͺ…", scale=4)
82
+ persona_description = gr.Textbox(lines=10, label="페λ₯΄μ†Œλ‚˜ μ„€λͺ…", value=get_random_persona_description(), scale=1)
83
+ with gr.Row():
84
+ random_world_button = gr.Button(value="λ¬΄μž‘μœ„ 세계 μ„€λͺ… κ°€μ Έμ˜€κΈ°", variant="secondary", scale=1)
85
+ submit_button = gr.Button(value="ν₯미둜운 캐릭터 μƒμ„±ν•˜κΈ°!", variant="primary", scale=5)
86
+ random_persona_button = gr.Button(value="λ¬΄μž‘μœ„ 페λ₯΄μ†Œλ‚˜ μ„€λͺ… κ°€μ Έμ˜€κΈ°", variant="secondary", scale=1)
87
+ with gr.Row():
88
+ character_image = gr.Image(label="캐릭터 이미지")
89
+ character_json = gr.JSON(label="캐릭터 μ„€λͺ…")
90
+
91
+ examples = gr.Examples(
92
+ [
93
+ "λ§ˆλ²•μ΄ μ‹€μ‘΄ν•˜κ³  μš©λ“€μ΄ ν•˜λŠ˜μ„ λ‚ μ•„λ‹€λ‹ˆλŠ” μ„Έκ³„μ—μ„œ, λͺ¨ν—˜κ°€λ“€μ˜ 일행이 전섀적인 μš©μ™•μ˜ 검을 μ°Ύμ•„ λ‚˜μ„­λ‹ˆλ‹€.",
94
+ "에토리아에 μ˜€μ‹  것을 ν™˜μ˜ν•©λ‹ˆλ‹€. 이곳은 물리 법칙이 κ³ λŒ€ λ§ˆλ²•μ˜ μ˜μ§€μ— 따라 νœ˜μ–΄μ§€λŠ” κ΄‘ν™œν•˜κ³  μ‹ λΉ„λ‘œμš΄ μ˜μ—­μž…λ‹ˆλ‹€. 이 μ„Έκ³„λŠ” λμ—†λŠ” ν•˜λŠ˜μ— λ–  μžˆλŠ” μˆ˜λ§Žμ€ λΆ€μœ  μ„¬μœΌλ‘œ κ΅¬μ„±λ˜μ–΄ 있으며, 각 섬은 생λͺ…κ³Ό λΉ„λ°€λ‘œ 가득 μ°¬ λ…νŠΉν•œ μƒνƒœκ³„μž…λ‹ˆλ‹€. μ—ν† λ¦¬μ•„μ˜ 섬듀은 μšΈμ°½ν•œ μ •κΈ€λΆ€ν„° ν™©λŸ‰ν•œ μˆ˜μ • μ‚¬λ§‰κΉŒμ§€ λ‹€μ–‘ν•©λ‹ˆλ‹€. μ–΄λ–€ 섬은 λ„μ‹œ λΈ”λ‘λ§ŒνΌ μž‘κ³ , μ–΄λ–€ 섬은 수백 λ§ˆμΌμ— 걸쳐 μžˆμŠ΅λ‹ˆλ‹€. 이 λΆ„λ¦¬λœ 땅덩어리듀을 μ—°κ²°ν•˜λŠ” 것은 μˆœμˆ˜ν•œ μ—λ„ˆμ§€λ‘œ λ§Œλ“€μ–΄μ§„ λ°˜μ§μ΄λŠ” 닀리이며, beaten pathλ₯Ό λ²—μ–΄λ‚  만�� μš©κ°ν•œ μ‚¬λžŒλ“€μ€ λ¨Ό 거리λ₯Ό μˆœκ°„μ μœΌλ‘œ 이동할 수 μžˆλŠ” μˆ¨κ²¨μ§„ 포털을 찾을 수 μžˆμŠ΅λ‹ˆλ‹€. μ—ν† λ¦¬μ•„μ˜ 주민듀은 κ·Έ ν’κ²½λ§ŒνΌμ΄λ‚˜ λ‹€μ–‘ν•©λ‹ˆλ‹€. 인간듀은 λΉ›μ˜ μ—ν…Œλ₯΄ 쑴재, λ°”μœ„ ν”ΌλΆ€λ₯Ό 가진 거인, λΆ„λ₯˜ν•˜κΈ° μ–΄λ €μš΄ λ³€ν˜• 생물듀과 κ³΅μ‘΄ν•©λ‹ˆλ‹€. κ³ λŒ€ μœ μ λ“€μ΄ 섬듀을 점점이 μž₯μ‹ν•˜κ³  μžˆμ–΄, κ³Όν•™κ³Ό λ§ˆλ²•μ˜ 경계λ₯Ό νλ¦¬λŠ” μžŠν˜€μ§„ λ¬Έλͺ…κ³Ό κΈ°μˆ μ„ μ•”μ‹œν•©λ‹ˆλ‹€. μ„Έκ³„λŠ” μ—ν…Œλ₯΄λΌλŠ” μ‹ λΉ„ν•œ 물질둜 움직이며, 이것은 λͺ¨λ“  것을 톡해 νλ¦…λ‹ˆλ‹€. μ—ν…Œλ₯΄μ˜ νž˜μ„ λ‹€λ£° 수 μžˆλŠ” μ‚¬λžŒλ“€μ€ ν˜„μ‹€ 자체λ₯Ό μ‘°μž‘ν•  수 μžˆλŠ” κ°•λ ₯ν•œ λ§ˆλ²•μ‚¬κ°€ λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μ—ν…Œλ₯΄λŠ” ν•œμ •λœ μžμ›μ΄λ©°, κ·Έ ν¬μ†Œμ„±μœΌλ‘œ 인해 ν†΅μ œκΆŒμ„ 놓고 λ‹€νˆ¬λŠ” λ‹€μ–‘ν•œ μ„Έλ ₯ 사이에 κ°ˆλ“±μ΄ μƒκ²ΌμŠ΅λ‹ˆλ‹€. 섬듀 μ‚¬μ΄μ˜ ν•˜λŠ˜μ—μ„œλŠ” μ›…μž₯ν•œ 비행선듀이 λ§ˆλ²•μ˜ κΈ°λ₯˜λ₯Ό 타고 ν•­ν•΄ν•˜λ©° 무역과 νƒν—˜μ„ μ΄‰μ§„ν•©λ‹ˆλ‹€. 해적듀과 ν•˜λŠ˜ μŠ΅κ²©μžλ“€μ΄ ꡬ름 κΉŠμˆ™ν•œ 곳에 μˆ¨μ–΄ λ°©μ‹¬ν•œ λ¨Ήμž‡κ°μ„ 항상 노리고 μžˆμŠ΅λ‹ˆλ‹€. λΆ€μœ ν•˜λŠ” λ•… κΉŠμˆ™νžˆ μ•„λž˜μ—λŠ” μ–Έλ”λ³΄μ΄λ“œλΌλŠ” μ–΄λ‘‘κ³  μœ„ν—˜ν•œ μ˜μ—­μ΄ 있으며, μ•…λͺ½ 같은 생물듀과 말둜 ν‘œν˜„ν•  수 μ—†λŠ” λΆ€κ°€ κ°€λ“ν•©λ‹ˆλ‹€. 였직 κ°€μž₯ μš©κ°ν•œ λͺ¨ν—˜κ°€λ“€λ§Œμ΄ κ·Έ 깊이λ₯Ό νƒν—˜ν•˜λ € ν•˜κ³ , 더 적은 수만이 κ·Έ 이야기λ₯Ό λ“€λ €μ£ΌκΈ° μœ„ν•΄ λŒμ•„μ˜΅λ‹ˆλ‹€. 항상 μ‘΄μž¬ν•˜λŠ” μœ„ν˜‘μœΌλ‘œ, 혼돈의 폭풍이 μ•Œλ €μ§„ μ„Έκ³„μ˜ κ°€μž₯μžλ¦¬μ—μ„œ λ§Ήμœ„λ₯Ό λ–¨μΉ˜λ©° κ·Έ 길에 μžˆλŠ” λͺ¨λ“  것을 μ‚ΌμΌœλ²„λ¦΄ μœ„ν˜‘μ„ κ°€ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ—ν† λ¦¬μ•„μ˜ μ˜μ›…λ“€μ—κ²Œ μ„Έκ³„μ˜ 비밀을 밝히고 λ„ˆλ¬΄ 늦기 전에 λ‹€κ°€μ˜€λŠ” 어둠을 물리칠 방법을 μ°ΎλŠ” μž„λ¬΄κ°€ μ£Όμ–΄μ‘ŒμŠ΅λ‹ˆλ‹€. μ—ν† λ¦¬μ•„μ—μ„œλŠ” λͺ¨λ“  섬이 이야기λ₯Ό ν’ˆκ³  있고, λͺ¨λ“  생물이 비밀을 가지고 있으며, λͺ¨λ“  λͺ¨ν—˜μ΄ 이 경이둭고 μœ„ν—˜μ— μ²˜ν•œ μ„Έκ³„μ˜ 운λͺ…을 λ°”κΏ€ 수 μžˆμŠ΅λ‹ˆλ‹€.",
95
+ "제 상상 속 μ„Έκ³„μ—λŠ” 'μ˜€λΌν‚€μŠ€'λΌλŠ” λ„μ‹œκ°€ μžˆμŠ΅λ‹ˆλ‹€. 이 λ„μ‹œλŠ” μˆœμˆ˜ν•œ λΉ›μ˜ κΈ°λ‘₯ μœ„μ— λ–  μžˆμŠ΅λ‹ˆλ‹€. λ„μ‹œμ˜ 벽은 μˆ˜μ • 유리둜 λ§Œλ“€μ–΄μ Έ μžˆμ–΄ 항상 μƒˆλ²½κ³Ό ν™©ν˜Όμ˜ 색을 λ°˜μ‚¬ν•˜λ©° μ˜μ›ν•œ μ²œμƒμ˜ 광채λ₯Ό λ°œν•©λ‹ˆλ‹€. 건물듀은 κ³„μ ˆμ— 따라 μˆ¨μ„ 쉬며 ν˜•νƒœλ₯Ό λ°”κΏ‰λ‹ˆλ‹€ - λ΄„μ—λŠ” μ„±μž₯ν•˜κ³ , μ—¬λ¦„μ—λŠ” 강해지며, κ°€μ„μ—λŠ” ν‡΄μƒ‰ν•˜κΈ° μ‹œμž‘ν•΄ 겨울이 되면 μ•ˆκ°œκ°€ λ©λ‹ˆλ‹€.",
96
+ ],
97
+ world_description,
98
+ )
99
+
100
+ submit_button.click(
101
+ generate_character, [world_description, persona_description], outputs=[character_json]
102
+ ).then(fn=infer_flux, inputs=[character_json], outputs=[character_image])
103
+ random_world_button.click(
104
+ get_random_world_description, outputs=[world_description]
105
+ )
106
+ random_persona_button.click(
107
+ get_random_persona_description, outputs=[persona_description]
108
+ )
109
+
110
+ app.queue().launch(share=False)