commit f94ffb47214afb0a837e6044bd4518ba1492ae43
parent 6d32586a0c88aa43cbd94a3eb4a4327cfa71d86b
Author: Minerva-Juppiter <ryouturn@gmail.com>
Date: Mon, 14 Aug 2023 09:18:12 +0900
Diffstat:
11 files changed, 301 insertions(+), 120 deletions(-)
diff --git a/A3RTService.cs b/A3RTService.cs
@@ -0,0 +1,77 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Aida_chiyo_Talk_app
+{
+ internal class A3RTService
+ {
+ private string APIKEY;
+
+ /// <summary>
+ /// コンストラクタ
+ /// </summary>
+ internal A3RTService()
+ {
+ // App.configから設定を取得
+ APIKEY = "DZZqpz3HVnJL4LGk57u8ZfmgfAIjrB3B";
+
+ // 必要な情報が取得できない場合はエラー
+ if (string.IsNullOrEmpty(APIKEY))
+ {
+ throw new ArgumentException("A3RT_APIKEY is empty");
+ }
+ }
+
+ /// <summary>
+ /// 対話APIを実行し、応答文を返す
+ /// </summary>
+ /// <param name="message">発言</param>
+ /// <returns>応答</returns>
+ internal async Task<string> MakeRequestAsync(string message)
+ {
+ HttpClient client = new HttpClient();
+
+ // リクエストURL
+ string uri = $"https://api.a3rt.recruit-tech.co.jp/talk/v1/smalltalk";
+
+ // リクエスト本文
+ var content = new FormUrlEncodedContent(
+ new Dictionary<string, string>
+ {
+ { "apikey", APIKEY },
+ { "query", message }
+ });
+
+ // APIを実行し、レスポンス本文を取得
+ HttpResponseMessage response = await client.PostAsync(uri, content);
+ JObject rss = await response.Content.ReadAsAsync<JObject>();
+
+ // HTTPステータスが異常であればエラー
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new ApplicationException(
+ $"API failed. code={response.StatusCode}");
+ }
+
+ // 何も返さなかった場合は、何か埋めて返しておく
+ if ((int)rss["status"] == 2000)
+ {
+ return "...";
+ }
+ // APIがエラーを出していればエラー
+ else if ((int)rss["status"] != 0)
+ {
+ Console.WriteLine(rss);
+ throw new ApplicationException(
+ $"API failed. ");
+ }
+
+ // レスポンス本文から応答文のみを抽出して返す
+ return (string)rss["results"][0]["reply"];
+ }
+ }
+}
diff --git a/Aida chiyo Talk app.csproj b/Aida chiyo Talk app.csproj
@@ -12,6 +12,22 @@
<PackageReference Include="IronPython" Version="3.4.1" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
<PackageReference Include="Microsoft.ML" Version="2.0.1" />
+ <PackageReference Include="System.Windows.Extensions" Version="7.0.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Update="Python.py">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
+ <None Update="RinnaAIPython.cmd">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Update="RinnaAIPython.exe">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ <None Update="RinnaAIPython.py">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </None>
</ItemGroup>
</Project>
diff --git a/MainController.cs b/MainController.cs
@@ -25,67 +25,22 @@ namespace Aida_chiyo_Talk_app
public void Talkcon()
{
Inputs inputs = new Inputs();
- string input = inputs.InputConsole();
+ //string input = inputs.InputConsole();
- TalkEngine talkEngine = new TalkEngine();
- string answer = talkEngine.CallTalkAPI(input).ToString();
-
- Console.WriteLine(answer);
- }
-
- public void PythonTest()
- {
- Inputs inputs = new Inputs();
- string input = inputs.InputConsole();
-
- var script = @"
- def get_x():
- import torch
- return 1";
+ var output = new Output();
- var engine = Python.CreateEngine();
- dynamic scope = engine.CreateScope();
- engine.Execute(script, scope);
+ TalkAI talkAI = new TalkAI();
+ talkAI.TalkAIcon();
- var x = scope.get_x();
- Console.WriteLine("x is {0}", x);
+ talkAI.A3RTcon();
/*
- ScriptRuntime py = Python.CreateRuntime();
- dynamic script = py.UseFile("Python.py");
-
- string importPy = string.Empty;
- try
- {
- importPy = script.ToString();
- }catch (Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- if (importPy == "import is true")
- {
- Console.WriteLine("import was ended");
- }
- else
- {
- Console.WriteLine("import was not ended");
- Console.WriteLine(importPy);
- }
-
- string loadmodel = string.Empty;
- try
- {
- loadmodel = script.ToString();
- }catch(Exception ex)
- {
- Console.WriteLine(ex.ToString());
- }
- if(loadmodel == "importModel_is_true")
- {
- Console.WriteLine("Model was loaded");
- }
- else
+ TalkEngine talkEngine = new TalkEngine();
+ string answer = talkEngine.CallTalkAPI(input).ToString();
+ while (input != "exit")
{
- Console.WriteLine("model was not loaded");
+ answer = talkEngine.CallTalkAPI(input).ToString();
+ output.OutputConsole(answer);
+ input = inputs.InputConsole();
}
*/
}
diff --git a/Output.cs b/Output.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Aida_chiyo_Talk_app
+{
+ internal class Output
+ {
+ public void OutputConsole(string output)
+ {
+ Console.WriteLine(output);
+ }
+ }
+}
diff --git a/Python.py b/Python.py
@@ -0,0 +1 @@
+print("Python was called")+
\ No newline at end of file
diff --git a/Python.spec b/Python.spec
@@ -0,0 +1,50 @@
+# -*- mode: python ; coding: utf-8 -*-
+
+
+block_cipher = None
+
+
+a = Analysis(
+ ['Python.py'],
+ pathex=[],
+ binaries=[],
+ datas=[],
+ hiddenimports=[],
+ hookspath=[],
+ hooksconfig={},
+ runtime_hooks=[],
+ excludes=[],
+ win_no_prefer_redirects=False,
+ win_private_assemblies=False,
+ cipher=block_cipher,
+ noarchive=False,
+)
+pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
+
+exe = EXE(
+ pyz,
+ a.scripts,
+ [],
+ exclude_binaries=True,
+ name='Python',
+ debug=False,
+ bootloader_ignore_signals=False,
+ strip=False,
+ upx=True,
+ console=True,
+ disable_windowed_traceback=False,
+ argv_emulation=False,
+ target_arch=None,
+ codesign_identity=None,
+ entitlements_file=None,
+)
+coll = COLLECT(
+ exe,
+ a.binaries,
+ a.zipfiles,
+ a.datas,
+ strip=False,
+ upx=True,
+ upx_exclude=[],
+ name='Python',
+)
diff --git a/RinnaAIPython.cmd b/RinnaAIPython.cmd
@@ -0,0 +1,6 @@
+
+@echo off
+rem This script was created by Nuitka to execute 'RinnaAIPython.exe' with Python DLL being found.
+set PATH=c:\users\tetsu\appdata\local\programs\python\PYTHON~2;%PATH%
+set PYTHONHOME=C:\Users\tetsu\AppData\Local\Programs\Python\Python310
+"%~dp0.\RinnaAIPython.exe" %*
diff --git a/RinnaAIPython.exe b/RinnaAIPython.exe
Binary files differ.
diff --git a/RinnaAIPython.py b/RinnaAIPython.py
@@ -1,44 +0,0 @@
-# coding: shift-jis
-import torch
-from transformers import AutoTokenizer, AutoModelForCausalLM
-
-print("we are loading model")
-
-# モデルのダウンロード。
-tokenizer = AutoTokenizer.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft", use_fast=False)
-model = AutoModelForCausalLM.from_pretrained("rinna/japanese-gpt-neox-3.6b-instruction-sft")
-
-# GPUが使える状態なら使用する。
-device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
-model = model.to(device)
-
-print("model was loaded")
-
-# 対話の開始
-#print("会話を始めましょう!何か質問して下さい。")
-while True:
- #user_input = input("ユーザー: ")
- user_input = input()
-
- # ユーザーの入力をプロンプトに追加
- prompt = f"<NL>ユーザー: {user_input}<NL>システム: "
-
- # プロンプトをrinnaに与えて、回答を生成する。
- token_ids = tokenizer.encode(prompt, add_special_tokens=False, return_tensors="pt").to(device)
-
- with torch.no_grad():
- output_ids = model.generate(
- token_ids,
- do_sample=True,
- max_length=128,
- temperature=0.7,
- pad_token_id=tokenizer.pad_token_id,
- bos_token_id=tokenizer.bos_token_id,
- eos_token_id=tokenizer.eos_token_id
- )
-
- # rinnaからの回答を取得する。
- output = tokenizer.decode(output_ids.tolist()[0][token_ids.size(1):])
- output = output.replace("<NL>", "\n")
- #print("システム:", output)
- print(output)-
\ No newline at end of file
diff --git a/TalkAI.cs b/TalkAI.cs
@@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Reflection;
using System.Text;
using System.Threading.Tasks;
@@ -10,21 +11,26 @@ namespace Aida_chiyo_Talk_app
{
internal class TalkAI
{
- public String FileName { get; set; }
- public String WorkingDirectory { get; set; }
- public String Arguments { get; set; }
- public String InputString { get; set; }
- public String StandardOutput { get; set; }
+ public String FileName = string.Empty;
+ //public String Arguments = @"C:\Users\tetsu\source\repos\Aida chiyo Talk app\RinnaAIPython.dist\RinnaAIPython.exe";
+ public string Arguments = @"C:\Users\tetsu\source\repos\Aida chiyo Talk app\dist\Python\Python.exe";
+ public String InputString = string.Empty;
public int ExitCode { get; set; }
- private StringBuilder standardOutputStringBuilder = new StringBuilder();
- public string TalkAIcon()
+ public void TalkAIcon()
{
+ string answer;
+ //Assembly Assembly = Assembly.GetEntryAssembly();
+ //string WorkingDirectory = Assembly.Location;
+ //where is python
+ Output output = new Output();
+ Inputs inputs = new Inputs();
+ FileName = @"RinnaAIPython.cmd";
+
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.FileName = FileName;
- processStartInfo.WorkingDirectory = WorkingDirectory;
- processStartInfo.Arguments = Arguments;
-
+ //processStartInfo.WorkingDirectory = WorkingDirectory;
+ //processStartInfo.Arguments = Arguments;
processStartInfo.CreateNoWindow = true;
processStartInfo.UseShellExecute = false;
processStartInfo.RedirectStandardInput = true;
@@ -33,24 +39,42 @@ namespace Aida_chiyo_Talk_app
Process process = new System.Diagnostics.Process();
process.StartInfo = processStartInfo;
- process.OutputDataReceived += Process_OutputDataReceived;
- process.ErrorDataReceived += Process_ErrorDataReceived;
process.Start();
+ output.OutputConsole("calling Python");
- using(StreamWriter streamWriter = process.StandardInput)
+
+ Console.WriteLine(process.StandardOutput.ReadLine());
+ answer = process.StandardOutput.ReadLine();
+ while (answer != "model was loaded")
{
- streamWriter.Write(InputString);
+ if(answer != null)
+ {
+ output.OutputConsole(answer);
+ }
}
+
+ output.OutputConsole("model was loaded");
- process.BeginOutputReadLine();
- process.BeginErrorReadLine();
+ InputString = inputs.InputConsole();
- process.WaitForExit();
- this.ExitCode = process.ExitCode;
- this.StandardOutput = standardOutputStringBuilder.ToString();
+ VoiceVox voiceVox = new VoiceVox();
+ while (InputString != "exit")
+ {
+ process.StandardInput.WriteLine(InputString);
+ answer = process.StandardOutput.ReadLine();
+ while(answer == null)
+ {
+ }
+ answer = answer.Replace("</s>", "");
+ output.OutputConsole(answer);
+ voiceVox.VoiceVoxCon(answer);
+ InputString = inputs.InputConsole();
+ }
+ this.ExitCode = process.ExitCode;
+ Console.WriteLine(ExitCode.ToString());
}
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
@@ -62,5 +86,19 @@ namespace Aida_chiyo_Talk_app
{
throw new NotImplementedException();
}
+
+
+ public void A3RTcon()
+ {
+ A3RTService a3RTService = new A3RTService();
+ Inputs inputs = new Inputs();
+ Output output = new Output();
+ string input = inputs.InputConsole();
+ while (true)
+ {
+ output.OutputConsole(a3RTService.MakeRequestAsync(input).ToString());
+ input = inputs.InputConsole();
+ }
+ }
}
}
diff --git a/VoiceVox.cs b/VoiceVox.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Media;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Aida_chiyo_Talk_app
+{
+ internal class VoiceVox
+ {
+ public async Task VoiceVoxCon(string input)
+ {
+ //https://qiita.com/oyahun/items/e01e56878dc011cdc094
+
+ using (var httpClient = new HttpClient())
+ {
+ string query;
+ int speaker = 1;
+ string text = input;
+
+ // 音声クエリを生成
+ using (var request = new HttpRequestMessage(new HttpMethod("POST"), $"http://localhost:50021/audio_query?text={text}&speaker={speaker}"))
+ {
+ request.Headers.TryAddWithoutValidation("accept", "application/json");
+
+ request.Content = new StringContent("");
+ request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded");
+
+ var response = await httpClient.SendAsync(request);
+
+ query = response.Content.ReadAsStringAsync().Result;
+ //Console.WriteLine(query);
+ }
+
+ // 音声クエリから音声合成
+ using (var request = new HttpRequestMessage(new HttpMethod("POST"), "http://localhost:50021/synthesis?speaker=1&enable_interrogative_upspeak=true"))
+ {
+ request.Headers.TryAddWithoutValidation("accept", "audio/wav");
+
+ request.Content = new StringContent(query);
+ request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
+
+ var response = await httpClient.SendAsync(request);
+
+ // 音声を保存
+ using (var fileStream = System.IO.File.Create("test.wav"))
+ {
+ using (var httpStream = await response.Content.ReadAsStreamAsync())
+ {
+ httpStream.CopyTo(fileStream);
+ fileStream.Flush();
+ }
+ }
+ }
+ }
+
+ //読み込む
+ var player = new SoundPlayer("test.wav");
+ //再生する
+ player.PlaySync();
+ //Console.WriteLine("再生完了");
+ }
+ }
+}