aivmlib-web
Version:
Aivis Voice Model File (.aivm/.aivmx) Utility Library for Web
1 lines • 50.8 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { Base64 } from 'js-base64';\nimport * as $protobuf from 'protobufjs';\nimport * as uuid from 'uuid';\n\nimport { onnx } from '@/onnx-protobuf/onnx';\nimport { AivmMetadata, AivmManifest, AivmManifestSchema, DefaultAivmManifest } from '@/schemas/aivm-manifest';\nimport { DEFAULT_ICON_DATA_URL } from '@/schemas/aivm-manifest-constants';\nimport { StyleBertVITS2HyperParameters, StyleBertVITS2HyperParametersSchema } from '@/schemas/style-bert-vits2';\n\n// 各スキーマをすべてエクスポート\nexport * from '@/schemas/aivm-manifest';\nexport * from '@/schemas/style-bert-vits2';\nexport * from '@/schemas/aivm-manifest-constants';\n\n\n/**\n * Aivis Voice Model File (.aivm/.aivmx) Utility Library\n *\n * AIVM / AIVMX ファイルフォーマットの仕様は下記ドキュメントを参照のこと\n * ref: https://github.com/Aivis-Project/aivmlib#aivm-specification\n */\nexport default class Aivmlib {\n\n /**\n * ハイパーパラメータとスタイルベクトルファイルを読み込み、バリデーションする内部メソッド\n * @param model_architecture 音声合成モデルのアーキテクチャ\n * @param hyper_parameters_file ハイパーパラメータファイル\n * @param style_vectors_file スタイルベクトルファイル\n * @returns ハイパーパラメータとスタイルベクトルのデータ\n */\n private static async loadAndValidateHyperParametersAndStyleVectors(\n model_architecture: AivmManifest['model_architecture'],\n hyper_parameters_file: File,\n style_vectors_file: File | null,\n ): Promise<{ hyper_parameters: StyleBertVITS2HyperParameters, style_vectors: Uint8Array }> {\n\n // Style-Bert-VITS2 系の音声合成モデルの場合\n if (['Style-Bert-VITS2', 'Style-Bert-VITS2 (JP-Extra)'].includes(model_architecture)) {\n\n // ハイパーパラメータファイルの読み込みとバリデーション\n const hyper_parameters_content = await hyper_parameters_file.text();\n let hyper_parameters: StyleBertVITS2HyperParameters;\n try {\n hyper_parameters = StyleBertVITS2HyperParametersSchema.parse(JSON.parse(hyper_parameters_content));\n } catch (error) {\n console.error(error);\n throw new Error(`${model_architecture} のハイパーパラメータファイルの形式が正しくありません。`, { cause: error });\n }\n\n // 話者情報とスタイル情報の存在チェック\n if (Object.keys(hyper_parameters.data.spk2id).length === 0) {\n throw new Error('ハイパーパラメータに話者情報が含まれていません。');\n }\n if (Object.keys(hyper_parameters.data.style2id).length === 0) {\n throw new Error('ハイパーパラメータにスタイル情報が含まれていません。');\n }\n\n // 話者 ID の重複チェック\n const speaker_ids = new Set<number>();\n for (const [speaker_name, speaker_id] of Object.entries(hyper_parameters.data.spk2id)) {\n if (speaker_ids.has(speaker_id)) {\n throw new Error(`話者 ID(${speaker_id})が重複しています。複数の話者(${Array.from(Object.entries(hyper_parameters.data.spk2id))\n .filter(([_, id]) => id === speaker_id)\n .map(([name, _]) => `「${name}」`)\n .join('、')})に同じ ID が割り当てられています。`);\n }\n speaker_ids.add(speaker_id);\n }\n\n // スタイル ID の重複チェック\n const style_ids = new Set<number>();\n for (const [style_name, style_id] of Object.entries(hyper_parameters.data.style2id)) {\n if (style_ids.has(style_id)) {\n throw new Error(`スタイル ID(${style_id})が重複しています。複数のスタイル(${Array.from(Object.entries(hyper_parameters.data.style2id))\n .filter(([_, id]) => id === style_id)\n .map(([name, _]) => `「${name}」`)\n .join('、')})に同じ ID が割り当てられています。`);\n }\n style_ids.add(style_id);\n }\n\n // スタイル ID のバリデーション\n // AIVM マニフェストの制約(0 <= id <= 31)を満たしているかチェック\n for (const [style_name, style_id] of Object.entries(hyper_parameters.data.style2id)) {\n if (style_id < 0 || style_id > 31) {\n throw new Error(`スタイル「${style_name}」の ID(${style_id})が有効範囲外です。スタイル ID は 0 から 31 の範囲である必要があります。`);\n }\n }\n\n // 話者 ID のバリデーション\n for (const [speaker_name, speaker_id] of Object.entries(hyper_parameters.data.spk2id)) {\n if (speaker_id < 0 || !Number.isInteger(speaker_id)) {\n throw new Error(`話者「${speaker_name}」の ID(${speaker_id})が有効範囲外です。話者 ID は 0 以上の整数である必要があります。`);\n }\n }\n\n // スタイルベクトルファイルの読み込み\n // Style-Bert-VITS2 モデルアーキテクチャの AIVM ファイルではスタイルベクトルが必須\n if (style_vectors_file === null) {\n throw new Error('スタイルベクトルファイルが指定されていません。');\n }\n const style_vectors_array_buffer = await style_vectors_file.arrayBuffer();\n const style_vectors = new Uint8Array(style_vectors_array_buffer);\n\n return { hyper_parameters, style_vectors };\n }\n\n throw new Error(`音声合成モデルアーキテクチャ ${model_architecture} には対応していません。`);\n }\n\n\n /**\n * ハイパーパラメータファイルとスタイルベクトルファイルから AIVM メタデータを生成する\n * @param model_architecture 音声合成モデルのアーキテクチャ\n * @param hyper_parameters_file ハイパーパラメータファイル\n * @param style_vectors_file スタイルベクトルファイル\n * @returns 生成された AIVM メタデータ\n */\n static async generateAivmMetadata(\n model_architecture: AivmManifest['model_architecture'],\n hyper_parameters_file: File,\n style_vectors_file: File | null,\n ): Promise<AivmMetadata> {\n\n // ハイパーパラメータとスタイルベクトルの読み込み・バリデーション\n const { hyper_parameters, style_vectors } = await Aivmlib.loadAndValidateHyperParametersAndStyleVectors(\n model_architecture,\n hyper_parameters_file,\n style_vectors_file,\n );\n\n // Style-Bert-VITS2 系の音声合成モデルの場合\n if (['Style-Bert-VITS2', 'Style-Bert-VITS2 (JP-Extra)'].includes(model_architecture)) {\n\n // デフォルトの AIVM マニフェストをコピーした後、ハイパーパラメータに記載の値で一部を上書きする\n const manifest = structuredClone(DefaultAivmManifest);\n manifest.name = hyper_parameters.model_name;\n // モデルアーキテクチャは Style-Bert-VITS2 系であれば異なる値が指定されても動作するよう、ハイパーパラメータの値を元に設定する\n manifest.model_architecture = hyper_parameters.data.use_jp_extra ? 'Style-Bert-VITS2 (JP-Extra)' : 'Style-Bert-VITS2';\n // モデル UUID はランダムに生成\n manifest.uuid = uuid.v4();\n\n // spk2id の内容を反映\n manifest.speakers = Object.keys(hyper_parameters.data.spk2id).map((speaker_name, speaker_id) => {\n return {\n // ハイパーパラメータに記載の話者名を使用\n name: speaker_name,\n // デフォルトアイコンを使用\n icon: DEFAULT_ICON_DATA_URL,\n // JP-Extra の場合は日本語のみ、それ以外は日本語・アメリカ英語・標準中国語をサポート\n supported_languages: hyper_parameters.data.use_jp_extra ? ['ja'] : ['ja', 'en-US', 'zh-CN'],\n // 話者 UUID はランダムに生成\n uuid: uuid.v4(),\n // ローカル ID は spk2id の ID の部分を使用\n local_id: speaker_id,\n // style2id の内容を反映\n styles: Object.keys(hyper_parameters.data.style2id).map((style_name, style_id) => {\n // \"Neutral\" はより分かりやすい \"ノーマル\" に変換する\n // ただし、既にスタイル名が \"ノーマル\" のスタイルがある場合は \"Neutral\" のままにする\n const new_style_name = (style_name === 'Neutral' && !Object.keys(hyper_parameters.data.style2id).includes('ノーマル'))\n ? 'ノーマル'\n : style_name;\n return {\n name: new_style_name,\n icon: null,\n local_id: style_id,\n voice_samples: [],\n };\n }),\n };\n });\n\n return {\n manifest: manifest,\n hyper_parameters: hyper_parameters,\n style_vectors: style_vectors,\n };\n }\n\n throw new Error(`音声合成モデルアーキテクチャ ${model_architecture} には対応していません。`);\n }\n\n\n /**\n * 既存の AIVM メタデータを、新しいハイパーパラメータとスタイルベクトルで更新する (モデル差し替え用)\n * 既存の UUID やユーザー設定メタデータは可能な限り維持される\n * @param existing_metadata 既存の AIVM メタデータ\n * @param hyper_parameters_file 新しいハイパーパラメータファイル\n * @param style_vectors_file 新しいスタイルベクトルファイル\n * @returns 更新された AIVM メタデータと警告メッセージの配列\n */\n static async updateAivmMetadata(\n existing_metadata: AivmMetadata,\n hyper_parameters_file: File,\n style_vectors_file: File | null,\n ): Promise<{ updated_metadata: AivmMetadata, warnings: string[] }> {\n const warnings: string[] = [];\n\n // 既存の AIVM マニフェストからモデルアーキテクチャを取得\n const model_architecture = existing_metadata.manifest.model_architecture;\n\n // ハイパーパラメータとスタイルベクトルの読み込み・バリデーション\n const { hyper_parameters, style_vectors } = await Aivmlib.loadAndValidateHyperParametersAndStyleVectors(\n model_architecture,\n hyper_parameters_file,\n style_vectors_file,\n );\n\n // Style-Bert-VITS2 系の音声合成モデルの場合\n if (['Style-Bert-VITS2', 'Style-Bert-VITS2 (JP-Extra)'].includes(model_architecture)) {\n\n // 新しい話者・スタイル情報を取得\n const new_spk2id = hyper_parameters.data.spk2id;\n const new_style2id = hyper_parameters.data.style2id;\n\n // 指定された既存の AIVM マニフェストをコピーした後、ハイパーパラメータの記述に応じてモデルアーキテクチャを更新\n // NOTE: 音声合成モデル名は更新せず、既存の AIVM マニフェストの内容を維持している\n const manifest = structuredClone(existing_metadata.manifest);\n manifest.model_architecture = hyper_parameters.data.use_jp_extra ? 'Style-Bert-VITS2 (JP-Extra)' : 'Style-Bert-VITS2';\n\n // Map: local_id -> speaker_name\n const new_spk_id_to_name_map = new Map<number, string>();\n for (const [name, id] of Object.entries(new_spk2id)) {\n new_spk_id_to_name_map.set(id, name);\n }\n // Map: local_id -> style_name\n const new_style_id_to_name_map = new Map<number, string>();\n for (const [name, id] of Object.entries(new_style2id)) {\n new_style_id_to_name_map.set(id, name);\n }\n const processed_new_speaker_local_ids = new Set<number>();\n const updated_speakers: AivmManifest['speakers'] = [];\n\n // 既存の話者情報リストを基準にイテレート\n for (const existing_speaker of existing_metadata.manifest.speakers) {\n const speaker_local_id = existing_speaker.local_id;\n\n // 既存話者の local_id が新しいハイパーパラメータの spk2id に存在するか確認\n if (new_spk_id_to_name_map.has(speaker_local_id)) {\n processed_new_speaker_local_ids.add(speaker_local_id);\n const processed_new_style_local_ids = new Set<number>();\n const updated_styles: AivmManifest['speakers'][number]['styles'] = [];\n\n // 既存のスタイル情報リストを基準にイテレート\n for (const existing_style of existing_speaker.styles) {\n const style_local_id = existing_style.local_id;\n\n // 既存スタイルの local_id が新しいハイパーパラメータの style2id に存在するか確認\n if (new_style_id_to_name_map.has(style_local_id)) {\n processed_new_style_local_ids.add(style_local_id);\n\n // 既存のスタイル情報を維持\n updated_styles.push(existing_style);\n } else {\n // スタイルが削除された場合\n warnings.push(`話者「${existing_speaker.name}」のスタイル「${existing_style.name}」(ID: ${style_local_id}) は、新しいハイパーパラメータに存在しないため削除されます。`);\n }\n }\n\n // 新しいハイパーパラメータで追加されたスタイルを追加\n for (const [style_name, style_local_id] of Object.entries(new_style2id)) {\n if (!processed_new_style_local_ids.has(style_local_id)) {\n // \"Neutral\" はより分かりやすい \"ノーマル\" に変換する\n // ただし、既にスタイル名が \"ノーマル\" のスタイルがある場合は \"Neutral\" のままにする\n const new_style_name = (style_name === 'Neutral' && !Object.keys(hyper_parameters.data.style2id).includes('ノーマル'))\n ? 'ノーマル'\n : style_name;\n updated_styles.push({\n name: new_style_name,\n icon: null,\n local_id: style_local_id,\n voice_samples: [],\n });\n warnings.push(`話者「${existing_speaker.name}」にスタイル「${style_name}」(ID: ${style_local_id}) が新しく追加されました。`);\n }\n }\n\n // モデルアーキテクチャが変更された場合に備え、supported_languages を計算し直す\n // JP-Extra の場合は日本語のみ、それ以外は日本語・アメリカ英語・標準中国語をサポート\n let supported_languages = existing_speaker.supported_languages;\n const new_supported_languages = hyper_parameters.data.use_jp_extra ? ['ja'] : ['ja', 'en-US', 'zh-CN'];\n if (JSON.stringify(supported_languages) !== JSON.stringify(new_supported_languages)) {\n supported_languages = new_supported_languages;\n warnings.push(`話者「${existing_speaker.name}」の対応言語が変更されました: ${supported_languages.join(', ')}`);\n }\n\n // 更新された話者情報を追加\n updated_speakers.push({\n ...existing_speaker, // 既存の話者情報を維持\n supported_languages: supported_languages, // 更新された対応言語情報\n styles: updated_styles, // 更新されたスタイル情報リスト\n });\n\n } else {\n // 話者が削除された場合\n warnings.push(`話者「${existing_speaker.name}」 (ID: ${existing_speaker.local_id}) は、新しいハイパーパラメータに存在しないため削除されます。`);\n }\n }\n\n // 新しいハイパーパラメータで追加された話者を追加\n for (const [new_speaker_name, new_local_id] of Object.entries(new_spk2id)) {\n if (!processed_new_speaker_local_ids.has(new_local_id)) {\n\n // 新しいハイパーパラメータに含まれる全スタイルを追加\n const new_speaker_styles: AivmManifest['speakers'][number]['styles'] = [];\n for (const [style_name, style_local_id] of Object.entries(new_style2id)) {\n // \"Neutral\" はより分かりやすい \"ノーマル\" に変換する\n // ただし、既にスタイル名が \"ノーマル\" のスタイルがある場合は \"Neutral\" のままにする\n const new_style_name = (style_name === 'Neutral' && !Object.keys(hyper_parameters.data.style2id).includes('ノーマル'))\n ? 'ノーマル'\n : style_name;\n new_speaker_styles.push({\n name: new_style_name,\n icon: null,\n local_id: style_local_id,\n voice_samples: [],\n });\n }\n\n // 新しい話者を追加\n updated_speakers.push({\n // ハイパーパラメータに記載の話者名を使用\n name: new_speaker_name,\n // デフォルトアイコンを使用\n icon: DEFAULT_ICON_DATA_URL,\n // JP-Extra の場合は日本語のみ、それ以外は日本語・アメリカ英語・標準中国語をサポート\n supported_languages: hyper_parameters.data.use_jp_extra ? ['ja'] : ['ja', 'en-US', 'zh-CN'],\n // 話者 UUID はランダムに生成\n uuid: uuid.v4(),\n // ローカル ID は spk2id の ID の部分を使用\n local_id: new_local_id,\n // style2id の内容を反映\n styles: new_speaker_styles,\n });\n warnings.push(`話者「${new_speaker_name}」(ID: ${new_local_id}) が新しく追加されました。`);\n }\n }\n\n // マニフェストに更新された話者情報リストを設定\n manifest.speakers = updated_speakers;\n\n // 処理の結果、話者情報リストが空になった場合はエラーを投げる\n if (updated_speakers.length === 0) {\n throw new Error('更新処理の結果、話者情報が空になりました。AIVM マニフェストには少なくとも 1 つの話者が必要です。');\n }\n\n // 処理の結果、いずれかの話者のスタイル情報リストが空になった場合はエラーを投げる\n for (const speaker of updated_speakers) {\n if (speaker.styles.length === 0) {\n throw new Error(`更新処理の結果、話者「${speaker.name}」(ID: ${speaker.local_id}) のスタイル情報が空になりました。各話者には少なくとも 1 つのスタイルが必要です。`);\n }\n }\n\n return {\n updated_metadata: {\n manifest: manifest,\n hyper_parameters: hyper_parameters,\n style_vectors: style_vectors,\n },\n warnings: warnings,\n };\n }\n\n throw new Error(`音声合成モデルアーキテクチャ ${model_architecture} には対応していません。`);\n }\n\n\n /**\n * AIVM メタデータをバリデーションする\n * @param raw_metadata 辞書形式の生のメタデータ\n * @returns バリデーションが完了した AIVM メタデータ\n */\n static validateAivmMetadata(raw_metadata: { [key: string]: string }): AivmMetadata {\n\n // AIVM マニフェストが存在しない場合\n if (!raw_metadata || !raw_metadata['aivm_manifest']) {\n throw new Error('AIVM マニフェストが見つかりません。');\n }\n\n // AIVM マニフェストのバリデーション\n let aivm_manifest: AivmManifest;\n try {\n aivm_manifest = AivmManifestSchema.parse(JSON.parse(raw_metadata['aivm_manifest']));\n } catch (error) {\n console.error(error);\n throw new Error('AIVM マニフェストの形式が正しくありません。', { cause: error });\n }\n\n // ハイパーパラメータのバリデーション\n let aivm_hyper_parameters: StyleBertVITS2HyperParameters;\n if (raw_metadata['aivm_hyper_parameters']) {\n try {\n if (['Style-Bert-VITS2', 'Style-Bert-VITS2 (JP-Extra)'].includes(aivm_manifest.model_architecture)) {\n aivm_hyper_parameters = StyleBertVITS2HyperParametersSchema.parse(JSON.parse(raw_metadata['aivm_hyper_parameters']));\n } else {\n throw new Error(`モデルアーキテクチャ ${aivm_manifest.model_architecture} のハイパーパラメータには対応していません。`);\n }\n } catch (error) {\n console.error(error);\n throw new Error('ハイパーパラメータの形式が正しくありません。', { cause: error });\n }\n } else {\n throw new Error('ハイパーパラメータが見つかりません。');\n }\n\n // スタイルベクトルのデコード\n let aivm_style_vectors: Uint8Array | undefined;\n if (raw_metadata['aivm_style_vectors']) {\n try {\n const base64_string: string = raw_metadata['aivm_style_vectors'];\n aivm_style_vectors = Base64.toUint8Array(base64_string);\n } catch (error) {\n throw new Error('スタイルベクトルのデコードに失敗しました。', { cause: error });\n }\n }\n\n return {\n manifest: aivm_manifest,\n hyper_parameters: aivm_hyper_parameters,\n style_vectors: aivm_style_vectors,\n };\n }\n\n\n /**\n * AIVM ファイルから AIVM メタデータを読み込む\n * @param aivm_file AIVM ファイル\n * @returns AIVM メタデータ\n */\n static async readAivmMetadata(aivm_file: File): Promise<AivmMetadata> {\n\n // ファイルの内容を読み込む\n const array_buffer = await aivm_file.arrayBuffer();\n const data_view = new DataView(array_buffer);\n\n // 先頭 8 バイトからヘッダーサイズを取得\n const header_size = data_view.getBigUint64(0, true);\n\n // ヘッダー部分を抽出\n let header_bytes: Uint8Array;\n try {\n header_bytes = new Uint8Array(array_buffer, 8, Number(header_size));\n } catch (error) {\n console.error(error);\n throw new Error('AIVM ファイルの形式が正しくありません。AIVM ファイル以外のファイルが指定されている可能性があります。', { cause: error });\n }\n const header_text = new TextDecoder('utf-8').decode(header_bytes);\n const header_json = JSON.parse(header_text);\n\n // \"__metadata__\" キーから AIVM メタデータを取得\n const raw_metadata = header_json['__metadata__'];\n\n // バリデーションを行った上で、AivmMetadata オブジェクトを構築して返す\n return Aivmlib.validateAivmMetadata(raw_metadata);\n }\n\n\n /**\n * AIVMX ファイルから AIVM メタデータを読み込む\n * @param aivmx_file AIVMX ファイル\n * @returns AIVM メタデータ\n */\n static async readAivmxMetadata(aivmx_file: File): Promise<AivmMetadata> {\n\n // ファイルの内容を読み込む\n const array_buffer = await aivmx_file.arrayBuffer();\n\n // ONNX モデル (Protobuf) をロード\n let model: onnx.IModelProto;\n try {\n const reader = new $protobuf.Reader(new Uint8Array(array_buffer));\n model = onnx.ModelProto.decode(reader);\n } catch (error) {\n console.error(error);\n throw new Error('AIVMX ファイルの形式が正しくありません。AIVMX ファイル以外のファイルが指定されている可能性があります。', { cause: error });\n }\n\n // AIVM メタデータを取得\n const raw_metadata: { [key: string]: string } = {};\n if (model.metadataProps) {\n for (const prop of model.metadataProps) {\n if (prop.key && prop.value) {\n raw_metadata[prop.key] = prop.value;\n }\n }\n }\n\n // バリデーションを行った上で、AivmMetadata オブジェクトを構築して返す\n return Aivmlib.validateAivmMetadata(raw_metadata);\n }\n\n\n /**\n * AIVM メタデータを生の辞書形式にシリアライズする\n * @param aivm_metadata AIVM メタデータ\n * @returns シリアライズされた AIVM メタデータ (文字列から文字列へのマップ)\n */\n static serializeAivmMetadata(aivm_metadata: AivmMetadata): { [key: string]: string } {\n\n // AIVM メタデータをシリアライズ\n // Safetensors / ONNX のメタデータ領域はネストなしの string から string への map でなければならないため、\n // すべてのメタデータを文字列にシリアライズして格納する\n const raw_metadata: { [key: string]: string } = {};\n raw_metadata['aivm_manifest'] = JSON.stringify(aivm_metadata.manifest);\n raw_metadata['aivm_hyper_parameters'] = JSON.stringify(aivm_metadata.hyper_parameters);\n\n // スタイルベクトルが存在する場合は Base64 エンコードして追加\n if (aivm_metadata.style_vectors) {\n raw_metadata['aivm_style_vectors'] = Base64.fromUint8Array(aivm_metadata.style_vectors);\n }\n\n return raw_metadata;\n }\n\n\n /**\n * AIVM メタデータを AIVM ファイルに書き込む\n * @param aivm_file AIVM ファイル\n * @param aivm_metadata AIVM メタデータ\n * @returns 書き込みが完了した AIVM ファイル\n */\n static async writeAivmMetadata(aivm_file: File, aivm_metadata: AivmMetadata): Promise<File> {\n\n // モデル形式を Safetensors に設定\n // AIVM ファイルのモデル形式は Safetensors のため、AIVM マニフェストにも明示的に反映する\n aivm_metadata.manifest.model_format = 'Safetensors';\n\n // AIVM マニフェストの内容をハイパーパラメータにも反映する\n // 結果は AivmMetadata オブジェクトに直接 in-place で反映される\n Aivmlib.applyAivmManifestToHyperParameters(aivm_metadata);\n\n // AIVM メタデータをシリアライズした上で、書き込む前にバリデーションを行う\n const raw_metadata = Aivmlib.serializeAivmMetadata(aivm_metadata);\n Aivmlib.validateAivmMetadata(raw_metadata);\n\n // AIVM ファイルの内容を一度に読み取る\n const aivm_file_buffer = await aivm_file.arrayBuffer();\n const aivm_file_bytes = new Uint8Array(aivm_file_buffer);\n\n // 既存のヘッダー JSON を取得\n const existing_header_size = new DataView(aivm_file_buffer).getBigUint64(0, true);\n const existing_header_bytes = aivm_file_bytes.slice(8, 8 + Number(existing_header_size));\n const existing_header_text = new TextDecoder('utf-8').decode(existing_header_bytes);\n let existing_header: { [key: string]: unknown };\n try {\n existing_header = JSON.parse(existing_header_text);\n } catch (error) {\n console.error(error);\n throw new Error('AIVM ファイルの形式が正しくありません。AIVM ファイル以外のファイルが指定されている可能性があります。', { cause: error });\n }\n\n // 既存の __metadata__ を取得または新規作成\n const existing_metadata = existing_header['__metadata__'] || {};\n\n // 既存の __metadata__ に新しいメタデータを追加\n // 既に存在するキーは上書きされる\n for (const key in raw_metadata) {\n existing_metadata[key] = raw_metadata[key];\n }\n\n // 更新された __metadata__ を設定\n existing_header['__metadata__'] = existing_metadata;\n\n // ヘッダー JSON を UTF-8 にエンコード\n const new_header_text = JSON.stringify(existing_header);\n const new_header_bytes = new TextEncoder().encode(new_header_text);\n\n // ヘッダーサイズを 8 バイトの符号なし Little-Endian 64bit 整数に変換\n const new_header_size = BigInt(new_header_bytes.length);\n const new_header_size_bytes = new Uint8Array(8);\n new DataView(new_header_size_bytes.buffer).setBigUint64(0, new_header_size, true);\n\n // 新しい AIVM ファイルの内容を作成\n const aivm_file_content = new Uint8Array(8 + new_header_bytes.length + (aivm_file_bytes.length - 8 - Number(existing_header_size)));\n aivm_file_content.set(new_header_size_bytes, 0);\n aivm_file_content.set(new_header_bytes, 8);\n aivm_file_content.set(aivm_file_bytes.slice(8 + Number(existing_header_size)), 8 + new_header_bytes.length);\n\n // 新しい AIVM ファイルを作成\n const new_aivm_file = new File([aivm_file_content], aivm_file.name, { type: aivm_file.type });\n\n return new_aivm_file;\n }\n\n\n /**\n * AIVM メタデータを AIVMX ファイルに書き込む\n * @param aivmx_file AIVMX ファイル\n * @param aivm_metadata AIVM メタデータ\n * @returns 書き込みが完了した AIVMX ファイル\n */\n static async writeAivmxMetadata(aivmx_file: File, aivm_metadata: AivmMetadata): Promise<File> {\n\n // モデル形式を ONNX に設定\n // AIVMX ファイルのモデル形式は ONNX のため、AIVM マニフェストにも明示的に反映する\n aivm_metadata.manifest.model_format = 'ONNX';\n\n // AIVM マニフェストの内容をハイパーパラメータにも反映する\n // 結果は AivmMetadata オブジェクトに直接 in-place で反映される\n Aivmlib.applyAivmManifestToHyperParameters(aivm_metadata);\n\n // ファイルの内容を読み込む\n const array_buffer = await aivmx_file.arrayBuffer();\n\n // ONNX モデル (Protobuf) をロード\n let model: onnx.IModelProto;\n try {\n const reader = new $protobuf.Reader(new Uint8Array(array_buffer));\n model = onnx.ModelProto.decode(reader);\n } catch (error) {\n console.error(error);\n throw new Error('AIVMX ファイルの形式が正しくありません。AIVMX ファイル以外のファイルが指定されている可能性があります。', { cause: error });\n }\n\n // AIVM メタデータをシリアライズした上で、書き込む前にバリデーションを行う\n const raw_metadata = Aivmlib.serializeAivmMetadata(aivm_metadata);\n Aivmlib.validateAivmMetadata(raw_metadata);\n\n // メタデータを ONNX モデルに追加\n if (!model.metadataProps) {\n model.metadataProps = [];\n }\n for (const key in raw_metadata) {\n // 同一のキーが存在する場合は上書き\n const existing_prop = model.metadataProps.find(prop => prop.key === key);\n if (existing_prop) {\n existing_prop.value = raw_metadata[key];\n } else {\n model.metadataProps.push({ key: key, value: raw_metadata[key] });\n }\n }\n\n // 新しい AIVMX ファイルの内容をシリアライズ\n const writer = onnx.ModelProto.encode(model);\n const aivmx_file_content = writer.finish();\n\n // 新しい AIVMX ファイルを作成\n const new_aivmx_file = new File([aivmx_file_content], aivmx_file.name, { type: aivmx_file.type });\n\n return new_aivmx_file;\n }\n\n\n /**\n * AIVM マニフェストの内容をハイパーパラメータにも反映する\n * 結果は AivmMetadata オブジェクトに直接 in-place で反映される\n * @param aivm_metadata AIVM メタデータ\n */\n static applyAivmManifestToHyperParameters(aivm_metadata: AivmMetadata): void {\n\n // Style-Bert-VITS2 系の音声合成モデルの場合\n if (['Style-Bert-VITS2', 'Style-Bert-VITS2 (JP-Extra)'].includes(aivm_metadata.manifest.model_architecture)) {\n\n // スタイルベクトルが設定されていなければエラー\n if (aivm_metadata.style_vectors === undefined) {\n throw new Error('スタイルベクトルが設定されていません。');\n }\n\n // モデル名を反映\n aivm_metadata.hyper_parameters.model_name = aivm_metadata.manifest.name;\n\n // 環境依存のパスが含まれるため、training_files と validation_files は固定値に変更\n aivm_metadata.hyper_parameters.data.training_files = 'train.list';\n aivm_metadata.hyper_parameters.data.validation_files = 'val.list';\n\n // 話者名を反映\n const new_spk2id: { [key: string]: number } = {};\n for (const speaker of aivm_metadata.manifest.speakers) {\n // 話者のローカル ID が元のハイパーパラメータに存在するかチェック\n const local_id = speaker.local_id;\n const old_key = Object.keys(aivm_metadata.hyper_parameters.data.spk2id).find(\n key => aivm_metadata.hyper_parameters.data.spk2id[key] === local_id\n );\n // 存在すれば新しい話者名をキーとして追加\n if (old_key) {\n new_spk2id[speaker.name] = local_id;\n } else {\n // 必ず AivmManifest.speakers[].local_id の値が spk2id に存在しなければならない\n throw new Error(`話者 ID \"${local_id}\" の話者 \"${speaker.name}\" がハイパーパラメータに存在しません。`);\n }\n }\n aivm_metadata.hyper_parameters.data.spk2id = new_spk2id;\n // n_speakers はモデル構造に関わるハイパーパラメータなので、もし spk2id の長さと一致していない場合でも絶対に変更すべきではない\n // 2話者モデルのうち1話者のみをハイパーパラメータから削除して事実上無効化したような場合に、\n // n_speakers の値 (2) を現在 spk2id の長さ (1) に合わせるとモデルロードに失敗する\n\n // スタイル名を反映\n const new_style2id: { [key: string]: number } = {};\n for (const speaker of aivm_metadata.manifest.speakers) {\n for (const style of speaker.styles) {\n // スタイルのローカル ID が元のハイパーパラメータに存在するかチェック\n const local_id = style.local_id;\n const old_key = Object.keys(aivm_metadata.hyper_parameters.data.style2id).find(\n key => aivm_metadata.hyper_parameters.data.style2id[key] === local_id\n );\n // 存在すれば新しいスタイル名をキーとして追加\n if (old_key) {\n new_style2id[style.name] = local_id;\n } else {\n // 必ず AivmManifest.speakers[].styles[].local_id の値が style2id に存在しなければならない\n throw new Error(`スタイル ID \"${local_id}\" のスタイル \"${style.name}\" がハイパーパラメータに存在しません。`);\n }\n }\n }\n aivm_metadata.hyper_parameters.data.style2id = new_style2id;\n aivm_metadata.hyper_parameters.data.num_styles = Object.keys(new_style2id).length;\n }\n }\n}\n"],"names":["Aivmlib","model_architecture","hyper_parameters_file","style_vectors_file","hyper_parameters_content","hyper_parameters","StyleBertVITS2HyperParametersSchema","error","speaker_ids","speaker_name","speaker_id","_","id","name","style_ids","style_name","style_id","style_vectors_array_buffer","style_vectors","manifest","DefaultAivmManifest","uuid","DEFAULT_ICON_DATA_URL","existing_metadata","warnings","new_spk2id","new_style2id","new_spk_id_to_name_map","new_style_id_to_name_map","processed_new_speaker_local_ids","updated_speakers","existing_speaker","speaker_local_id","processed_new_style_local_ids","updated_styles","existing_style","style_local_id","new_style_name","supported_languages","new_supported_languages","new_speaker_name","new_local_id","new_speaker_styles","speaker","raw_metadata","aivm_manifest","AivmManifestSchema","aivm_hyper_parameters","aivm_style_vectors","base64_string","Base64","aivm_file","array_buffer","header_size","header_bytes","header_text","aivmx_file","model","reader","$protobuf","onnx","prop","aivm_metadata","aivm_file_buffer","aivm_file_bytes","existing_header_size","existing_header_bytes","existing_header_text","existing_header","key","new_header_text","new_header_bytes","new_header_size","new_header_size_bytes","aivm_file_content","existing_prop","aivmx_file_content","local_id","style"],"mappings":"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"}