Playingyoyo commited on
Commit
a031d74
·
1 Parent(s): cea1960

Add aLLoyM MCP server code

Browse files
Files changed (2) hide show
  1. app.py +109 -0
  2. requirements.txt +8 -0
app.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import spaces
3
+ import torch
4
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig
5
+ from mcp.server.fastmcp import FastMCP
6
+ import os
7
+
8
+ # ---------------------------------------------------------
9
+ # 設定
10
+ MODEL_ID = "Playingyoyo/aLLoyM"
11
+ # ---------------------------------------------------------
12
+
13
+ # 1. 4bit量子化設定 (Unslothの load_in_4bit=True と同等)
14
+ bnb_config = BitsAndBytesConfig(
15
+ load_in_4bit=True,
16
+ bnb_4bit_compute_dtype=torch.bfloat16, # dtype = torch.bfloat16
17
+ bnb_4bit_use_double_quant=True,
18
+ bnb_4bit_quant_type="nf4"
19
+ )
20
+
21
+ print(f"Loading model: {MODEL_ID}...")
22
+
23
+ # トークナイザーのロード
24
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
25
+
26
+ # モデルのロード (ZeroGPUのCPUメモリに4bitで一度展開)
27
+ # device_map="auto" により、GPUが割り当てられた瞬間に自動転送されます
28
+ try:
29
+ model = AutoModelForCausalLM.from_pretrained(
30
+ MODEL_ID,
31
+ quantization_config=bnb_config,
32
+ device_map="auto",
33
+ trust_remote_code=True
34
+ )
35
+ print("Model loaded successfully!")
36
+ except Exception as e:
37
+ print(f"Error loading model: {e}")
38
+ model = None
39
+
40
+ # MCPサーバー初期化
41
+ mcp = FastMCP("AlloyM-ZeroGPU-Agent")
42
+
43
+ # 2. 推論実行関数 (@spaces.GPUでGPU確保)
44
+ @spaces.GPU(duration=120)
45
+ def infer_alloy(question: str):
46
+ if model is None:
47
+ return "Model failed to load."
48
+
49
+ # プロンプトの構築 (貴方のコードと同じ形式)
50
+ prompt = f"""### Instruction:
51
+ You are an expert in phase diagrams, thermodynamics, and materials science, specializing in binary alloy systems.
52
+
53
+ ### Input:
54
+ {question}
55
+
56
+ ### Output:
57
+ """
58
+
59
+ # トークナイズ & GPUへ転送
60
+ inputs = tokenizer(
61
+ [prompt],
62
+ return_tensors='pt',
63
+ truncation=True
64
+ ).to(model.device)
65
+
66
+ # 生成実行
67
+ with torch.no_grad():
68
+ outputs = model.generate(
69
+ **inputs,
70
+ max_new_tokens=512,
71
+ use_cache=True,
72
+ do_sample=False,
73
+ pad_token_id=tokenizer.eos_token_id
74
+ )
75
+
76
+ # デコードして回答部分のみ抽出
77
+ full_output = tokenizer.batch_decode(outputs, skip_special_tokens=True)[0]
78
+
79
+ if "### Output:" in full_output:
80
+ return full_output.split("### Output:")[1].strip()
81
+ else:
82
+ return full_output.strip()
83
+
84
+ # 3. MCPツール定義
85
+ @mcp.tool()
86
+ async def ask_alloym(question: str) -> str:
87
+ """
88
+ Ask aLLoyM specific questions about alloy phase diagrams.
89
+ Example: 'What phases form when Arsenic (40%) + Platinum (60%) are mixed at 400 K?'
90
+ """
91
+ # 同期関数を呼び出す
92
+ return infer_alloy(question)
93
+
94
+ # 4. Gradio UI
95
+ with gr.Blocks() as demo:
96
+ gr.Markdown(f"# {MODEL_ID} MCP Server")
97
+ gr.Markdown("ZeroGPU + 4bit Quantization (Equivalent to Unsloth Inference)")
98
+
99
+ with gr.Row():
100
+ inp = gr.Textbox(label="Question", placeholder="What phases form when...")
101
+ out = gr.Textbox(label="Answer")
102
+
103
+ btn = gr.Button("Ask aLLoyM")
104
+ btn.click(infer_alloy, inputs=inp, outputs=out)
105
+
106
+ mcp.mount_gradio_app(demo, path="/")
107
+
108
+ if __name__ == "__main__":
109
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ mcp
2
+ gradio
3
+ transformers
4
+ torch
5
+ accelerate
6
+ spaces
7
+ bitsandbytes
8
+ peft