trtd56 commited on
Commit
94f49c6
·
2 Parent(s): 633269ac472f9c

branch check

Browse files
Files changed (3) hide show
  1. README.md +23 -6
  2. app.py +173 -0
  3. requirements.txt +6 -0
README.md CHANGED
@@ -1,12 +1,29 @@
1
  ---
2
- title: Bash Explainer
3
- emoji:
4
- colorFrom: red
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.9.0
8
  app_file: app.py
9
  pinned: false
 
 
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Bash Command Explainer JA
3
+ emoji: "💻"
4
+ colorFrom: yellow
5
+ colorTo: blue
6
  sdk: gradio
7
+ sdk_version: 5.50.0
8
  app_file: app.py
9
  pinned: false
10
+ models:
11
+ - trtd56/LFM2.5-1.2B-JP-bash-explainer-lora
12
  ---
13
 
14
+ # Bash Command Explainer JA
15
+
16
+ `trtd56/LFM2.5-1.2B-JP-bash-explainer-lora` を使って、bash コマンドを日本語で説明する Gradio Space です。
17
+
18
+ ## Input
19
+
20
+ - bash コマンド文字列
21
+
22
+ ## Output
23
+
24
+ - コマンドの意味を説明する短い日本語
25
+
26
+ ## Notes
27
+
28
+ - コマンドは実行せず、説明だけを返します。
29
+ - 学習データは `response -> prompt_ja` の向きで整形した dataset を使っています。
app.py ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ import gradio as gr
4
+ import torch
5
+ from peft import AutoPeftModelForCausalLM
6
+ from transformers import AutoTokenizer
7
+
8
+
9
+ MODEL_ID = os.getenv("MODEL_ID", "trtd56/LFM2.5-1.2B-JP-bash-explainer-lora")
10
+ SYSTEM_PROMPT = "あなたは Bash コマンドの内容を説明する日本語アシスタントです。"
11
+
12
+
13
+ def load_model():
14
+ model = AutoPeftModelForCausalLM.from_pretrained(
15
+ MODEL_ID,
16
+ torch_dtype="auto",
17
+ device_map="auto",
18
+ )
19
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, use_fast=True)
20
+ if tokenizer.pad_token is None:
21
+ tokenizer.pad_token = tokenizer.eos_token
22
+ return model, tokenizer
23
+
24
+
25
+ MODEL, TOKENIZER = load_model()
26
+
27
+
28
+ def build_prompt(command: str) -> str:
29
+ return (
30
+ f"{SYSTEM_PROMPT}\n\n"
31
+ "### 入力\n"
32
+ f"{command.strip()}\n\n"
33
+ "### 出力\n"
34
+ )
35
+
36
+
37
+ def explain_command(command: str, max_new_tokens: int) -> str:
38
+ command = command.strip()
39
+ if not command:
40
+ return "bash コマンドを入力してください。"
41
+
42
+ prompt = build_prompt(command)
43
+ inputs = TOKENIZER(prompt, return_tensors="pt")
44
+ model_device = next(MODEL.parameters()).device
45
+ inputs = {k: v.to(model_device) for k, v in inputs.items()}
46
+
47
+ with torch.no_grad():
48
+ output = MODEL.generate(
49
+ **inputs,
50
+ max_new_tokens=max_new_tokens,
51
+ do_sample=False,
52
+ pad_token_id=TOKENIZER.pad_token_id,
53
+ eos_token_id=TOKENIZER.eos_token_id,
54
+ )
55
+
56
+ text = TOKENIZER.decode(output[0], skip_special_tokens=True)
57
+ if "### 出力" in text:
58
+ return text.split("### 出力", 1)[-1].strip()
59
+ return text.strip()
60
+
61
+
62
+ EXAMPLES = [
63
+ ["sudo apt install curl"],
64
+ ["ls -la ~/Downloads"],
65
+ ['grep -R "TODO" .'],
66
+ ['find . -name "*.log" -delete'],
67
+ ]
68
+
69
+ CSS = """
70
+ :root {
71
+ --bg: #f4efe4;
72
+ --card: #fffaf0;
73
+ --ink: #1d1a16;
74
+ --muted: #6b6254;
75
+ --line: #d8ccb8;
76
+ --accent: #9a3412;
77
+ --accent-2: #164e63;
78
+ }
79
+ .gradio-container {
80
+ background:
81
+ radial-gradient(circle at top left, rgba(154, 52, 18, 0.10), transparent 28%),
82
+ radial-gradient(circle at bottom right, rgba(22, 78, 99, 0.10), transparent 24%),
83
+ var(--bg);
84
+ color: var(--ink);
85
+ font-family: "IBM Plex Sans JP", "Hiragino Sans", sans-serif;
86
+ }
87
+ .shell-card {
88
+ border: 1px solid var(--line);
89
+ border-radius: 20px;
90
+ background: linear-gradient(180deg, rgba(255,250,240,0.98), rgba(255,247,235,0.98));
91
+ box-shadow: 0 18px 60px rgba(29, 26, 22, 0.08);
92
+ }
93
+ .eyebrow {
94
+ letter-spacing: 0.08em;
95
+ text-transform: uppercase;
96
+ color: var(--accent-2);
97
+ font-size: 12px;
98
+ font-weight: 700;
99
+ }
100
+ .hero {
101
+ font-family: "Avenir Next", "IBM Plex Sans JP", sans-serif;
102
+ font-size: 38px;
103
+ line-height: 1.05;
104
+ font-weight: 700;
105
+ margin: 8px 0 12px;
106
+ }
107
+ .sub {
108
+ color: var(--muted);
109
+ font-size: 15px;
110
+ line-height: 1.7;
111
+ }
112
+ """
113
+
114
+
115
+ with gr.Blocks(css=CSS, theme=gr.themes.Soft()) as demo:
116
+ gr.HTML(
117
+ """
118
+ <div class="shell-card" style="padding: 28px; margin: 24px 0 18px;">
119
+ <div class="eyebrow">Bash Command Explainer</div>
120
+ <div class="hero">コマンドを貼ると、日本語で説明します。</div>
121
+ <div class="sub">
122
+ 学習済み LoRA <code>trtd56/LFM2.5-1.2B-JP-bash-explainer-lora</code> を読み込み、
123
+ bash コマンドの動作を短い日本語で返します。
124
+ </div>
125
+ </div>
126
+ """
127
+ )
128
+
129
+ with gr.Row():
130
+ with gr.Column(scale=3):
131
+ command = gr.Textbox(
132
+ label="Bash コマンド",
133
+ placeholder='例: find . -name "*.log" -delete',
134
+ lines=5,
135
+ )
136
+ with gr.Column(scale=1):
137
+ max_new_tokens = gr.Slider(
138
+ minimum=16,
139
+ maximum=128,
140
+ value=64,
141
+ step=8,
142
+ label="最大生成トークン",
143
+ )
144
+ run_btn = gr.Button("説明する", variant="primary")
145
+ clear_btn = gr.Button("クリア")
146
+
147
+ output = gr.Textbox(label="日本語説明", lines=6, show_copy_button=True)
148
+
149
+ gr.Examples(
150
+ examples=EXAMPLES,
151
+ inputs=[command],
152
+ label="Examples",
153
+ )
154
+
155
+ gr.Markdown(
156
+ "注意: ここではコマンドを実行せず、内容を説明するだけです。削除系コマンドも安全に試せます。"
157
+ )
158
+
159
+ run_btn.click(
160
+ fn=explain_command,
161
+ inputs=[command, max_new_tokens],
162
+ outputs=output,
163
+ )
164
+ command.submit(
165
+ fn=explain_command,
166
+ inputs=[command, max_new_tokens],
167
+ outputs=output,
168
+ )
169
+ clear_btn.click(lambda: ("", ""), outputs=[command, output])
170
+
171
+
172
+ if __name__ == "__main__":
173
+ demo.queue().launch()
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ gradio>=5.50.0
2
+ torch
3
+ transformers>=4.46.0
4
+ peft>=0.13.0
5
+ accelerate>=0.34.0
6
+ safetensors>=0.4.5