File size: 7,359 Bytes
dbcbd54
 
 
 
 
 
1f1caf1
bef283b
d9257a1
0738a1d
35b13b1
4ce8184
 
 
 
 
 
d9257a1
900fe2a
d9257a1
 
1f1caf1
 
 
dbcbd54
d9257a1
 
1f1caf1
 
 
 
 
 
 
e053ab0
dbcbd54
1f1caf1
 
 
d8006d1
1f1caf1
 
 
 
bef283b
 
1f1caf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29a14b0
774c0ee
 
 
621b0e0
 
e053ab0
1f1caf1
181b7f6
1f1caf1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dbcbd54
1f1caf1
29a14b0
1f1caf1
37be3e6
 
1f1caf1
 
 
 
 
 
 
d9257a1
42a19c1
38768c6
 
 
e053ab0
1f1caf1
 
 
 
 
 
59afc08
1f1caf1
900fe2a
9a31b48
 
 
1f1caf1
 
900fe2a
38768c6
900fe2a
 
d9257a1
1f1caf1
 
0ab9df5
 
29a14b0
1f1caf1
900fe2a
38768c6
 
0ab9df5
 
 
38768c6
29a14b0
 
38768c6
29a14b0
42a19c1
1f1caf1
 
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
143
144
145
146
147
148
import os
import argparse
from pathlib import Path

import chatglm_cpp
import gradio as gr


class myChatMessage(chatglm_cpp.ChatMessage):
    def __deepcopy__(self, memo):
        return myChatMessage(self.role, self.content)
    def __getstate__(self):
        """Used for serializing instances"""
        return (self.role, self.content)
    def __setstate__(self, state):
        """Used for deserializing"""
        self.role, self.content = state

init_history = [
    myChatMessage(role="user", content='你讀過《故事課》嗎?'),
    myChatMessage(role="assistant", content='''作為一個 AI 模型,我沒有「讀」過任何書籍,但我對《故事課》這本書有一定的了解。《故事課》是一本關於故事創作和 storytelling 的書籍,作者是美国作家 John D. Walsh。

這本書提供了一些有用的建議和技巧,幫助讀者如何創作出引人入勝的故事。它涵蓋了故事創作的各個方面,包括故事結構、角色塑造、情節設計和語言表達等。此外,這本書還提供了一些實用的例子和案例分析,讓讀者可以更好地理解故事創作的過程和技巧。

總的來說,《故事課》是一本對故事創作很有幫助的書籍,尤其對於那些想寫故事或想提高自己故事創作能力的人來說,這本書會是一本很有價值的參考資料。'''),
    myChatMessage(role="user", content='《故事課》提到哪些故事公式?'),
    myChatMessage(role="assistant", content='''《故事課》這本書提到了一些故事公式或故事結構,這些結構可以幫助創作故事。以下是其中一些常見的故事公式:

1. 起承轉合:這是最基礎的故事結構,也稱為三幕結構。故事開始,然後有了一個轉折,接著是高潮,最後有了一個結局。
2. 英雄之旅:這是一個很常見的故事結構,也被稱為綠傳或 gray area。它描述了一個英雄從平凡無奇的生活中開始,經歷了一系列挑戰和冒險,最終達成目標的故事。
3. 成長故事:這是一個關於個人成長和發展的成長故事,它通常描述了一個人物從一個脆弱或不成熟的状态開始,通過經歷挑戰和學習,最終成長和成熟的故事。
4. 反轉结局:這是一個比較特別的结局,它通常在故事的最後出現,並且會對讀者產生一種意外的冲击和影響。
5. 寓言故事:這是一種用故事來說明一個道理或概念的故事,通常包含一個寓意或象徵性的元素。

這些故事公式只是故事創作中的一部分,不同的故事可能会有不同的結構和情節,但這些公式可以作為一個起點,幫助你開始創作出一個引人入勝的故事。''')
]

os.system("wget https://huggingface.co/npc0/chatglm3-6b-int4/resolve/main/chatglm3-ggml-q4_0.bin")

DEFAULT_MODEL_PATH = "./chatglm3-ggml-q4_0.bin"

parser = argparse.ArgumentParser()
parser.add_argument("-m", "--model", default=DEFAULT_MODEL_PATH, type=Path, help="model path")
parser.add_argument("--mode", default="chat", type=str, choices=["chat", "generate"], help="inference mode")
parser.add_argument("-l", "--max_length", default=8192, type=int, help="max total length including prompt and output")
parser.add_argument("-c", "--max_context_length", default=2048, type=int, help="max context length")
parser.add_argument("--top_k", default=0, type=int, help="top-k sampling")
parser.add_argument("--top_p", default=0.7, type=float, help="top-p sampling")
parser.add_argument("--temp", default=0.95, type=float, help="temperature")
parser.add_argument("--repeat_penalty", default=1.0, type=float, help="penalize repeat sequence of tokens")
parser.add_argument("-t", "--threads", default=0, type=int, help="number of threads for inference")
parser.add_argument("--plain", action="store_true", help="display in plain text without markdown support")
args = parser.parse_args()

pipeline = chatglm_cpp.Pipeline(args.model)


def postprocess(text):
    if args.plain:
        return f"<pre>{text}</pre>"
    return text


def predict(input, max_length, top_p, temperature, history):
    if input is None:
        return
    elif input.isdigit():
        input = '現在你作為一個專業的編劇,你需要為故事%s轉寫一段故事大綱提供一個完整的龍骨給之後的編劇用。' %input
    else:
        input = '請為『%s』提議五個適合的公式。' %input
    response = ""
    history.append(myChatMessage(role="user", content=input))

    generation_kwargs = dict(
        max_length=max_length,
        max_context_length=args.max_context_length,
        do_sample=temperature > 0,
        top_k=args.top_k,
        top_p=top_p,
        temperature=temperature,
        repetition_penalty=args.repeat_penalty,
        num_threads=args.threads,
        stream=True,
    )
    generator = (
        pipeline.chat(history, **generation_kwargs)
        if args.mode == "chat"
        else pipeline.generate(input, **generation_kwargs)
    )
    for response_piece in generator:
        response += response_piece.content

        yield postprocess(response), history

    history.append(myChatMessage(role=response_piece.role, content=response))
    yield response, history


def reset_user_input():
    return gr.update(value="")


def reset_state():
    history = gr.State(init_history)
    return '', '', history, gr.Dropdown(["1", "2", "3", "4", "5"], label="Step2:進一步擴展的範例", value=None, interactive=False)


def allow_user_input():
    return gr.Dropdown(["1", "2", "3", "4", "5"], label="Step2:進一步擴展的範例", interactive=True)


with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">劇本測試</h1>""")
    with gr.Row():
        with gr.Column(scale=4):
            user_input = gr.Textbox(show_label=False, placeholder="Step1:主題設定")
        with gr.Column(scale=1):
            submitBtn = gr.Button("Submit", variant="primary")
            max_length = gr.Slider(0, 2048, value=args.max_length, step=1.0, label="Maximum Length", interactive=True, visible=False)
            top_p = gr.Slider(0, 1, value=args.top_p, step=0.01, label="Top P", interactive=True, visible=False)
            temperature = gr.Slider(0, 1, value=args.temp, step=0.01, label="Temperature", interactive=True, visible=False)
            emptyBtn = gr.Button("Clear History")

    five_sample = gr.Textbox(show_label=False, placeholder="五個範例")
    expand = gr.Dropdown(["1", "2", "3", "4", "5"], label="Step2:進一步擴展的範例", interactive=False)
    final_sample = gr.Textbox(show_label=False, placeholder="大綱")

    history = gr.State(init_history)

    submitBtn.click(
        predict,
        [user_input, max_length, top_p, temperature, history],
        [five_sample, history], show_progress=True
    )
    submitBtn.click(reset_user_input, [], [final_sample])
    submitBtn.click(allow_user_input, [], [expand])
    
    expand.select(
        fn=predict,
        inputs=[expand, max_length, top_p, temperature, history],
        outputs=[final_sample, history])

    emptyBtn.click(reset_state,
                   outputs=[five_sample, final_sample, history, expand],
                   show_progress=True)
    emptyBtn.click(reset_user_input, [], [user_input])

demo.queue().launch(share=False, inbrowser=True)