[TTS] pmcとは

「TTS の PMC」という言葉は、文脈によって指しているものが異なりますが、
主に以下の2つの意味で使われることが多い。

結論からいうと、TTS(Text-to-Speech)分野でよく出てくる PMC = Prosody Model / Prosody Modification / Prosody Modeling Component の略として使われることがある。

1. Prosody Modeling Component(韻律モデル・韻律制御モジュール)
TTS が自然に聞こえるためには、
イントネーション(抑揚)
音の強弱
音の高さ(F0)
話速(テンポ)
間の取り方(ポーズ)
といった 韻律(Prosody) が非常に重要

これらを制御する仕組みを Prosody Modeling Component (PMC) と呼ぶ

特に以下のような論文や TTS アーキテクチャで登場する用語です:
Tacotron 系
FastSpeech 系
Prosody Embedding
Duration / Pitch / Energy Predictor

2. Prosody Modification Control(韻律変更コントロール)
TTS に emotion や表現力を持たせるときに必要な操作で、
PMC = Prosody Modification Control(韻律変換コントロール)
という意味で使われることもあります。

例:
ピッチカーブを直接操作する
話速/音素長を変える
感情(怒り、喜び、悲しみ)を調整
商用TTSエンジンや研究用TTSで PMC という言葉を使うケースがあります。

TTS の PMC = Prosody(韻律)に関係するモジュールの総称
Prosody Modeling Component
Prosody Modification Control
などの略として使われることが多い

PMC の役割
抑揚
強弱
音の高さ
話速
ポーズ
感情表現

これらを予測したり制御するのが PMC の仕事

[LLM] LangChain Docs

1. Models(モデル)
LLM や Embedding、画像モデルなど 外部AIモデル を扱うためのモジュール。

含まれる内容
Large Language Models(OpenAI, Anthropic, Azure, HuggingFace など)
ChatModels(チャット用インターフェース)
Embeddings(ベクトル化)
Text-to-Speech / Speech-to-Text
Vision Models

学べること
「複雑な API 呼び出しを、統一的なインターフェースで扱える」

例えば OpenAI と HuggingFace のモデルを同じコードスタイルで使えるようになる。

from langchain_community.llms import HuggingFaceHub
llm = HuggingFaceHub(repo_id=”mistralai/Mistral-7B-Instruct-v0.2″)

2. Prompts(プロンプト)
LLM に渡す指示文を構築・生成・管理する部分。
できること
Prompt Templates(テンプレート化)
Few-shot の自動選択
パラメータ差し込み
出力フォーマット強制(JSON化など)

学べること
「プロンプトをコードとして管理する仕組み」
from langchain.prompts import PromptTemplate

prompt = PromptTemplate.from_template(“要約して: {text}”)
prompt.format(text=”これはテスト文です”)

3. Chains(チェーン)
LLM・ツール・データ処理を パイプラインとしてつなぐ仕組み。
代表例
LLMChain
SequentialChain(複数ステップ実行)
SimpleSequentialChain
学べること

LLM → 加工 → LLM という流れを組み立てる。

from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run(“こんにちは”)

4. Agents(エージェント)
LLM が “自分でツールを選んで使う” 仕組み。
LangChain の最も特徴的な部分。
エージェントでできること
ツール使用(検索、計算、API呼び出し)
思考の分岐(ReAct)
マルチステップ問題解決
学べること
AI に “行動する力” を与える方法。

agent = initialize_agent(
tools=[search_tool, calculator],
llm=llm,
agent=”zero-shot-react-description”,
)
agent.run(“東京の天気を調べて摂氏で教えて”)

5. Retrieval(RAG:検索 + LLM)
外部データを読み込んで検索させる仕組み。
企業で一番使われるのがこれ。
主な機能

VectorStores(Chroma, Pinecone, Qdrant, FAISS)
Document loader(PDF, HTML, Notion, URL)
Retriever(検索器)
RAG チェーン全般

学べること

大量の社内文書を元に答えるチャットボットの実装方法。

from langchain.vectorstores import Chroma
db = Chroma.from_texts(texts, embeddings)
retriever = db.as_retriever()

[TTS] Flaskチャットに音声応答機能を統合

以下では OpenAI の TTS API(新しい audio API)を Flask チャットアプリで使う方法 を、
できるだけシンプルで実用的な構成で紹介します。

✅ 基本構成
Flaskでチャットアプリを作る場合、
Web画面でユーザーがテキスト入力
Flaskサーバーが OpenAI API に TTS リクエスト
得た音声バイナリ(mp3/wav)を返す
ブラウザ側で audio タグ / JS で再生
という流れになります。

📌 必要ライブラリ
pip install flask openai

🚀 サンプル:Flask + OpenAI TTS API
📁 app.py

from flask import Flask, request, send_file, jsonify
from openai import OpenAI
import os
import io

app = Flask(__name__)

# OpenAI API キー
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

@app.route("/")
def index():
    return """
    <form action="/tts" method="post">
        <input name="text" placeholder="Enter text">
        <button type="submit">Generate</button>
    </form>
    """

@app.route("/tts", methods=["POST"])
def tts():
    text = request.form.get("text", "")

    # OpenAI TTS API 呼び出し
    response = client.audio.speech.create(
        model="gpt-4o-mini-tts",     # OpenAI TTSモデル
        voice="alloy",               # 声(例:alloy / verse / shimmer など)
        input=text,
        format="mp3"
    )

    # バイナリ取得
    audio_bytes = response.read()

    # メモリ内に保存して返す
    return send_file(
        io.BytesIO(audio_bytes),
        mimetype="audio/mpeg",
        download_name="speech.mp3"
    )

if __name__ == "__main__":
    app.run(debug=True)

📌 ブラウザで音声を自動再生するフロント(例)

index.html を返すなら:

<!DOCTYPE html>
<html>
<body>
    <h2>OpenAI TTS Demo</h2>
    <input id="txt" placeholder="Enter text">
    <button onclick="speak()">Speak</button>
    <audio id="audio" controls></audio>

    <script>
        async function speak() {
            const text = document.getElementById("txt").value;

            const formData = new FormData();
            formData.append("text", text);

            const res = await fetch("/tts", { method: "POST", body: formData });
            const blob = await res.blob();

            const url = URL.createObjectURL(blob);
            document.getElementById("audio").src = url;
        }
    </script>
</body>
</html>

🔊 レスポンス形式の選択

OpenAI公式では以下が使えます:

形式 MIMEタイプ 特徴
mp3 audio/mpeg 一般的・最小サイズ
aac audio/aac 高音質
wav audio/wav ロスレス(重い)
flac audio/flac 高品質

[LLM] LangChain docs

LangChain Docs を “分かりやすく体系化” するとこうなる
LangChain のドキュメントは大きく次の 5 つの領域に分かれています:

1. Models(モデル)
LLM や Embedding、画像モデルなど 外部AIモデル を扱うためのモジュール。
含まれる内容
Large Language Models(OpenAI, Anthropic, Azure, HuggingFace など)
ChatModels(チャット用インターフェース)
Embeddings(ベクトル化)
Text-to-Speech / Speech-to-Text
Vision Models

学べること
「複雑な API 呼び出しを、統一的なインターフェースで扱える」
例えば OpenAI と HuggingFace のモデルを同じコードスタイルで使えるようになる。
from langchain_community.llms import HuggingFaceHub
llm = HuggingFaceHub(repo_id=”mistralai/Mistral-7B-Instruct-v0.2″)

2. Prompts(プロンプト)
LLM に渡す指示文を構築・生成・管理する部分。
できること
Prompt Templates(テンプレート化)
Few-shot の自動選択
パラメータ差し込み
出力フォーマット強制(JSON化など)

学べること
「プロンプトをコードとして管理する仕組み」
from langchain.prompts import PromptTemplate
prompt = PromptTemplate.from_template(“要約して: {text}”)
prompt.format(text=”これはテスト文です”)

3. Chains(チェーン)
LLM・ツール・データ処理を パイプラインとしてつなぐ仕組み。
代表例
LLMChain
SequentialChain(複数ステップ実行)
SimpleSequentialChain

学べること
LLM → 加工 → LLM という流れを組み立てる。
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
chain.run(“こんにちは”)

4. Agents(エージェント)
LLM が “自分でツールを選んで使う” 仕組み。
LangChain の最も特徴的な部分。

エージェントでできること
ツール使用(検索、計算、API呼び出し)
思考の分岐(ReAct)
マルチステップ問題解決

学べること
AI に “行動する力” を与える方法。

agent = initialize_agent(
tools=[search_tool, calculator],
llm=llm,
agent=”zero-shot-react-description”,
)
agent.run(“東京の天気を調べて摂氏で教えて”)

5. Retrieval(RAG:検索 + LLM)
外部データを読み込んで検索させる仕組み。
企業で一番使われるのがこれ。

主な機能
VectorStores(Chroma, Pinecone, Qdrant, FAISS)
Document loader(PDF, HTML, Notion, URL)
Retriever(検索器)
RAG チェーン全般

学べること
大量の社内文書を元に答えるチャットボットの実装方法。

from langchain.vectorstores import Chroma
db = Chroma.from_texts(texts, embeddings)
retriever = db.as_retriever()

🌟 補足モジュール
■ Memory(記憶)
チャットの文脈保持の仕組み。
会話履歴の保持
要約ベースのメモリ
永続化

■ Tools(ツール)
Python実行
Google検索
Database Query
API呼び出し

■ Output Parsers
JSON抽出
自然言語 → 構造化データ化

[Figma] UIデザインの基礎

1. UIデザインの基本は “3色構成”
UIの配色は、実は 3色で十分。
🔹① ベースカラー(背景)
白・薄いグレー・黒など
→ UIの土台になる色

🔹② メインカラー(ブランドカラー)
ロゴやサービスの印象を作る色
→ ボタン・リンク・アイコンなどで使う
→ 「一番よく使う色」

🔹③ アクセントカラー(補助)
注意喚起や強調したい場所に少量使う
→ 赤・黄色・緑のような “目に入る色” を控えめに
UIはこの 3色 + グレー階調(Gray-scale)で十分!
(5〜6色以上使うと素人っぽくなりがち)

3. 色の心理効果(UI向け)

色には心理的な印象があるため、UIの目的に合わせて使います。

色 心理効果・印象 UIでの用途例
青 信頼・清潔・知性 金融、SaaS、企業系UI
緑 安心・健康・自然 成功メッセージ、チェックマーク
赤 危険・注意・緊急 エラー、削除ボタン
黄 注意・明るさ 警告(Warning)
黒 高級・強さ モダンUI、文字色
グレー 中立・控えめ 背景、境界線、無効状態

4. コントラスト(可読性)の基礎
UIで一番重要なのが 可読性(文字が読みやすいか)。
💡基本ルール
文字色と背景色のコントラストを十分にする
ベースが白なら 文字は黒〜濃いグレー
背景色は薄い色(#F7F7F7 など)
ボタンの文字は「白 × 濃い色」 or 「濃い文字 × 淡いボタン色」
コントラストの指標(WCAG)
4.5:1 以上が推奨(一般文字)
3.0:1 以上(大きい文字)

5. カラーハーモニーの種類(UIでよく使う)
① モノクロマティック(同一色系)
1つの色の明度・彩度違い
→ UIデザインで最も安全
例:青 → 濃い青 → 薄い青 → グレー

② アナログ(類似色)
隣り合う色
→ 優しい・調和しやすい
例:青、青緑、緑

③ コンプリメンタリー(補色)
反対色
→ 注意喚起に最強(エラー・アクセント)
例:青 × オレンジ
例:緑 × 赤

6. Figmaでの配色運用(超基本)
🎨 色を決めたら Style に登録する
何かオブジェクトを選択
右パネル → Fill
四角のアイコン → +(Create style)
名前をつけて保存
/Colors
Primary / Blue 500
Primary / Blue 300
Accent / Red 500
Gray / 100〜900

こうすると…
色変更すると全画面に反映される
統一感が出る
開発者へ正しい値を渡せる(ハンドオフ)

7. 最初に決めるべき “UIカラーセット” サンプル
Primary: #0066FF
Primary Light: #E5F0FF
Primary Dark: #004FCC

Accent: #FF4D4D
Success: #22C55E
Warning: #FACC15
Error: #EF4444

Gray 900
Gray 700
Gray 500
Gray 300
Gray 100
White (#FFFFFF)

[iOS] Push通知

実際に「配信」するには サーバー・APNs・証明書 が必要なので複雑

✅ まずは “ローカル通知” の超簡単デモ(その場で動く通知)
プッシュ通知に進む前に、
iOS での 通知許可の取り方・通知の基本 が理解できます。
📌 サンプル:ボタンを押すと10秒後に通知が表示される
NotificationManager.swift

import Foundation
import UserNotifications

class NotificationManager {
    static let shared = NotificationManager()

    // 通知の許可をリクエスト
    func requestPermission() {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { success, error in
            if success {
                print("通知が許可されました")
            } else if let error = error {
                print("通知の許可エラー:", error)
            }
        }
    }

    // ローカル通知をスケジュール
    func scheduleNotification() {
        let content = UNMutableNotificationContent()
        content.title = "テスト通知"
        content.body = "10秒後に届く通知です"
        content.sound = .default

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)

        let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)

        UNUserNotificationCenter.current().add(request)
    }
}
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(spacing: 20) {
            Text("通知テスト")
                .font(.title)

            Button("通知を許可") {
                NotificationManager.shared.requestPermission()
            }

            Button("10秒後に通知送信") {
                NotificationManager.shared.scheduleNotification()
            }
        }
        .padding()
    }
}

iOSのプッシュ通知の本当の仕組み
あなたのサーバー → APNs(Appleの通知サーバー) → iPhoneに通知

1. アプリが Apple に「通知を受けたい」と登録
→ Apple が端末専用の デバイストークン(Device Token) を発行
→ アプリはこのトークンを サーバー に送る
2. サーバーはそのトークンを使って Apple(APNs) に通知を送る
→ Apple が iPhone にプッシュ通知を配信する

push通知を送る最低限のコード

import SwiftUI
import UserNotifications

@main
struct PushDemoApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    // 起動時に通知登録
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {

        UNUserNotificationCenter.current().delegate = self

        // 通知許可のリクエスト
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }

        return true
    }

    // APNs からデバイストークン取得
    func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        print("Device Token:", tokenString)
    }

    // トークン取得失敗時
    func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to get token:", error.localizedDescription)
    }
}

🔹 このコードでできること
通知許可ダイアログが表示される
トークンが取得できたら Xcode のコンソールに表示される
→ サーバーに送る必要がある

📌 注意
実際のプッシュ通知を送るには、さらに:
🔐 Apple Developer の作業が必要
APNs 証明書 or Key
Push Notifications を有効化
プロビジョニングプロファイル更新

🖥️ サーバー実装も必要(例:Python / Node.js / Firebase など)
APNs に対して HTTPS/JSON で通知を送る

[TTS] AzureでTTS APIを使う手順

1. サブスクリプションをupgrade

画面左上の「リソースの作成」または上部の検索バーで「Speech」と入力して検索します。
検索結果から「Speech」または「Azure AI サービス」を選択し、「作成」をクリックします。

サブスクリプション 課金が行われるアカウントです。 従量課金制にアップグレード済みのサブスクリプションを選択します。
リソース グループ 先ほど作成したグループです。 作成済みのリソースグループを選択します。
リージョン サービスがデプロイされる場所です。 アプリケーションのユーザーに近いリージョン、または性能・遅延が適切なリージョンを選択します。(例: East US、Japan Eastなど)
名前 このSpeechリソースの名称です。 任意の名前(例: MyTtsResource2025)を入力します。
価格レベル 料金プランです。 Standard (S0) を選択します。(無料枠を使い切っているため)

import azure.cognitiveservices.speech as speechsdk

# Azure Speech Service のキーとリージョン
speech_key = "YOUR_SPEECH_KEY"
service_region = "eastasia"   # East Asia リージョン

# SpeechConfig を作成
speech_config = speechsdk.SpeechConfig(subscription=speech_key, region=service_region)

# 出力音声を設定(標準はwav)
audio_config = speechsdk.audio.AudioOutputConfig(filename="output.wav")

# 音声の種類(例: 日本語の女性)
speech_config.speech_synthesis_voice_name = "ja-JP-NanamiNeural"

# Speech Synthesizer を作成
synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)

# 読み上げるテキスト
text = "こんにちは、これは Azure Text to Speech のテストです。"

# TTS 実行
result = synthesizer.speak_text_async(text).get()

# 結果チェック
if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
    print("✅ 音声ファイル 'output.wav' を生成しました")
else:
    print("❌ エラー:", result.reason)

Azureだと音声が全然違いますね!

[LLM] Hugging FaceのSpaceにuploadする

Hugging Face Spaces に Llama / Mistral のチャットデモを公開する最小構成

import gradio as gr
from transformers import AutoModelForCausalLM, AutoTokenizer, TextStreamer
import torch

# ここを Llama / Mistral など好きなモデルに変更
MODEL_NAME = "mistralai/Mistral-7B-Instruct-v0.2"
# MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"  # ← Llama に変更したい場合

# モデルとトークナイザのロード
tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
model = AutoModelForCausalLM.from_pretrained(
    MODEL_NAME,
    torch_dtype=torch.float16,
    device_map="auto"
)

def chat_fn(message, history):
    # 過去履歴を LLM のプロンプト形式に変換
    prompt = ""
    for user, assistant in history:
        prompt += f"<s>[ユーザー]: {user}\n[アシスタント]: {assistant}</s>\n"
    prompt += f"<s>[ユーザー]: {message}\n[アシスタント]:"

    inputs = tokenizer(prompt, return_tensors="pt").to(model.device)

    output_ids = model.generate(
        **inputs,
        max_new_tokens=200,
        temperature=0.7,
        do_sample=True,
        top_p=0.9
    )

    response = tokenizer.decode(output_ids[0], skip_special_tokens=True)

    # 最後のアシスタント発言だけ抽出
    if "[アシスタント]:" in response:
        response = response.split("[アシスタント]:")[-1].strip()

    history.append((message, response))
    return response, history


# Gradio UI
with gr.Blocks() as demo:
    gr.Markdown("# 🦙💬 Simple Llama / Mistral Chatbot")
    chatbot = gr.Chatbot()
    msg = gr.Textbox(label="Message")

    def user_send(user_message, chat_history):
        return "", chat_history + [[user_message, None]]

    msg.submit(user_send, [msg, chatbot], [msg, chatbot]).then(
        chat_fn, [msg, chatbot], [chatbot]
    )

demo.launch()

===== Application Startup at 2025-11-16 11:06:22 =====

tokenizer_config.json: 0%| | 0.00/2.10k [00:00

[LLM] Hugging Face で出来ること

Hugging Face は オープンソースLLMのプラットフォーム & コミュニティ
世界中のAIモデル・データセット・サンプルコードが集まるGitHub+App Store+AI研究コミュニティ

## Hugging Faceで何が出来る?
🤖 モデルHub Llama・Mistral・Gemma など数万のLLMをダウンロードして試せる
📚 データセットHub 研究用の巨大データセットが公開されていて利用可能
🚀 Transformers ライブラリ Python でLLMを簡単に使える神ライブラリ
🧪 Inference API / Endpoints GPUいらずでモデルをAPIとして利用できる
🧱 PEFT / LoRA サポート 軽量ファインチューニングが簡単
📊 Spaces(デモアプリ) Streamlit / Gradio でAIアプリをホスティング
🫂 AIコミュニティ モデル公開や議論・PRが活発で世界最大級

① Model Hub
世界中のLLMがここに集まっています。

例:
meta-llama/Llama-3.1-8B
mistralai/Mistral-7B
google/gemma-2-9b
EleutherAI/gpt-j-6b
GitHubと同じように、モデルごとにページがあり

説明
推奨ハイパーパラメータ
サンプルコード
重み(weights)
が公開されています。
→ とりあえず Hugging Face の中心はコレ と覚えればOK。

e.g.
https://huggingface.co/meta-llama/Llama-3.1-8B

### Transformer library

from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct")
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct")

inputs = tokenizer("こんにちは!自己紹介してください。", return_tensors="pt")
outputs = model.generate(**inputs, max_length=100)

print(tokenizer.decode(outputs[0], skip_special_tokens=True))

### Space(AIアプリ)
Gradio や Streamlit を使って、ブラウザで動くデモアプリを無料で公開できるサービス。

Mistral (ミストラル)
Mistralは、フランスのAIスタートアップ企業Mistral AIによって開発されているLLMのシリーズです。
開発元: Mistral AI (フランス)
主な特徴:
オープンソース/オープンウェイト: 多くのモデルがオープンソースまたはオープンウェイト(モデルの重み/パラメータが公開されている)で提供されており、研究者や開発者が自由に利用、改変、再配布しやすいのが大きな特徴です。

### Gradio、Streamlit
GradioとStreamlitは、どちらもPythonのコードのみで、機械学習モデルのデモやデータ分析のためのインタラクティブなWebアプリケーションを簡単に作成するためのライブラリ(フレームワーク)です。

Hugging Faceは、特にGradioの開発元を傘下に収めており、そのプラットフォーム「Hugging Face Spaces」でGradioとStreamlitのアプリケーションをホスティング(公開)できるようにしています。