PyTorch公式GitHub徹底解説!見るべきポイントを紹介


PyTorch公式GitHubリポジトリ徹底解説!見るべきポイントを紹介

はじめに:なぜPyTorchのGitHubリポジトリを見るべきなのか?

近年、機械学習、特にディープラーニングの分野は目覚ましい発展を遂げています。その進化を支える基盤の一つが、オープンソースの深層学習フレームワークです。中でも、Meta (旧Facebook) が開発を主導するPyTorchは、その柔軟性、使いやすさ、そして活発なコミュニティによって、研究開発から実運用まで幅広い分野で多くのユーザーに利用されています。

PyTorchを使ってモデルを構築し、学習させ、デプロイすることは、多くの開発者にとって日常的な作業となっています。しかし、PyTorchの内部がどのように設計され、どのように開発が進められているのか、さらには将来どのような機能が追加されるのかなど、その「裏側」に目を向けたことはあるでしょうか?

PyTorchの公式GitHubリポジトリ(pytorch/pytorch)は、まさにその「裏側」のすべてが公開されている場所です。単にソースコードが置かれているだけでなく、開発者コミュニティの議論、バグの報告、機能の提案、コードの変更履歴、そして将来のロードマップのヒントまで、PyTorchに関するありとあらゆる情報が集約されています。

では、なぜ私たちはこの公式GitHubリポジトリを「見るべき」なのでしょうか?その理由は多岐にわたります。

  1. PyTorchの内部構造と動作原理の理解: 高度な利用や、フレームワークの限界を超えるカスタマイズを行うためには、PyTorchが内部でどのようにテンソルを扱い、勾配を計算し、ハードウェア(CPU/GPU)と連携しているのかを理解することが不可欠です。ソースコードを読むことは、この理解への最も直接的な道です。
  2. 最新の開発状況の把握: 新機能の実装状況、進行中のバグ修正、パフォーマンス改善の取り組みなど、PyTorchの最前線で何が起こっているのかをリアルタイムに追跡できます。公式リリースを待つことなく、次に何が来るのかを知ることができます。
  3. 問題解決のヒント: 遭遇したバグがすでに報告されているか、またはその解決策が検討されているかを確認できます。他のユーザーが同じ問題に直面していないか、コミュニティがどのように対処しているのかを知ることは、自身でのデバッグに役立ちます。
  4. コントリビューションの機会: オープンソースプロジェクトであるPyTorchは、コミュニティからのコントリビューションを歓迎しています。バグ修正、新機能の実装、ドキュメントの改善など、PyTorchの開発に直接貢献したいと考えたとき、GitHubリポジトリはその活動の拠点となります。どのような貢献が必要とされているのか、どのように進めれば良いのか、具体的なプロセスを知ることができます。
  5. 高品質なコードと設計の学習: 世界中の優れたエンジニアや研究者によって書かれたコード、議論された設計判断に触れることは、自身のプログラミングスキルやソフトウェア設計思想を向上させる上で非常に貴重な経験となります。
  6. コミュニティとの交流: IssueやPull Request、Discussionなどを通じて、他のユーザーやコア開発者と直接コミュニケーションを取る機会があります。質問をしたり、意見を述べたり、議論に参加したりすることで、PyTorchコミュニティの一員として活動できます。

このように、公式GitHubリポジトリは、PyTorchをより深く理解し、活用し、さらには共に発展させていくための宝庫です。本記事では、PyTorchの公式GitHubリポジトリに焦点を当て、特に注目すべきポイントや、そこからどのような情報を得られるのかを徹底的に解説します。約5000語にわたる詳細な説明を通じて、読者の皆様がPyTorchのGitHubリポジトリを効果的に活用できるようになることを目指します。

PyTorch GitHubリポジトリの全体像

PyTorchの公式開発は、主にpytorchというGitHubオーガニゼーションの下で行われています。その中でも、PyTorchのコアライブラリのコードが置かれているのが、pytorch/pytorchリポジトリです。

PyTorch Core リポジトリ: pytorch/pytorch

このリポジトリは、PyTorchの根幹をなす部分、すなわちテンソルの定義、オペレーション(演算)の実装、自動微分エンジン、オプティマイザ、ニューラルネットワークモジュール(の一部)、さらには様々なバックエンド(CPU, CUDAなど)との連携を司るコードを含んでいます。

pytorch/pytorchリポジトリは、いわゆる「モノレポ」構造に近い形を採用しています。これは、関連性の高い複数のコンポーネントやライブラリを、単一のバージョン管理リポジトリ内で管理する開発戦略です。ただし、PyTorchのエコシステム全体が全てこのリポジトリにあるわけではなく、torchvision, torchaudio, torchtext, torchdata といったドメイン特化ライブラリや、チュートリアル、例などが別のリポジトリに分離されています。しかし、コアとなる機能の大部分はpytorch/pytorch内に集約されています。

リポジトリのトップレベルディレクトリを見ると、以下のような主要な構成要素が見て取れます(バージョンや開発状況によって変化する可能性はあります):

  • .github/: GitHub Actionsなど、GitHub固有の設定ファイル群。CI/CDパイプラインの定義などが含まれます。
  • aten/: “A Tensor Library” の略。PyTorchのテンソルオペレーション(add, mul, conv2d など)の定義と、バックエンドに依存しないカーネル実装の大部分がここにあります。C++で書かれており、PyTorchの計算グラフ実行において中心的な役割を果たします。
  • c10/: “Caffe2 Tenso Library” の略称が由来ですが、現在はPyTorchとCaffe2の両方で利用される共通の基盤ライブラリ群です。データ型、デバイス管理、ディスパッチメカニズム(異なるバックエンド実装を選択する仕組み)、アロケータなどが含まれます。PyTorchの低レベルな仕組みを理解する上で非常に重要です。
  • caffe2/: 元々は独立したフレームワークだったCaffe2のコードベース。PyTorchに統合され、ONNXエクスポートやモバイルデプロイなど、一部の機能で利用されています。
  • cmake/: CMakeビルドシステムの設定ファイル群。PyTorchをソースからビルドする際の挙動を定義します。
  • docs/: 公式ドキュメントのソースファイル(reStructuredText形式など)。ドキュメントの記述方法や詳細な説明を読みたい場合に役立ちます。
  • examples/: 簡単なサンプルコード。ただし、より網羅的な例やチュートリアルは pytorch/examplespytorch/tutorials リポジトリにあります。
  • include/: ヘッダーファイル群。C++ APIを使う場合や、カスタムオペレーションを実装する場合に関わってきます。
  • lib/: 外部ライブラリとの連携コードなど。
  • requirements/: 依存関係リスト。ビルド時やテスト時に必要なPythonパッケージなどが定義されています。
  • test/: 非常に広範なテストコード。PyTorchの各機能が正しく動作するかを確認するためのテストが網羅されています。特定の機能の正しい使い方や、エッジケースでの振る舞いを知るための強力な情報源です。
  • torch/: PyTorchのPythonフロントエンド。ユーザーがPythonコードでimport torchとして利用する部分のコードがここにあります。高レベルなAPI定義、ニューラルネットワークモジュール(torch.nn)、オプティマイザ(torch.optim)、データローダー(torch.utils.data)などの実装が含まれます。PyTorchの使い慣れたAPIが内部でどのようにC++バックエンドと連携しているのかを理解できます。
  • tools/: 開発、ビルド、テスト、ドキュメント生成などに使われる各種ユーティリティスクリプト。開発ワークフローや貢献プロセスを理解する上で役立ちます。

これらのディレクトリは、PyTorchが単なるPythonライブラリではなく、低レベルなC++コード、ビルドシステム、テストインフラなど、様々なコンポーネントから構成される複雑なシステムであることを示しています。各ディレクトリの役割を把握することは、リポジトリ内を探索する上で非常に役立ちます。

関連リポジトリ

前述したように、PyTorchのエコシステムはpytorch/pytorchだけに留まりません。主要な関連リポジトリには以下のものがあります。

  • pytorch/vision, pytorch/audio, pytorch/text: それぞれ画像処理、音声処理、自然言語処理のためのドメイン特化ライブラリ。一般的なデータセット、モデル、変換処理などが含まれます。これらも活発に開発が行われています。
  • pytorch/data: データ処理のための新しいライブラリ群(torchdata)。パイプライン処理などを効率的に行うための機能が含まれます。
  • pytorch/examples, pytorch/tutorials: 様々なモデルの実装例や、PyTorchの機能の使い方を学べるチュートリアル。公式ドキュメントサイトとも連携しています。
  • pytorch/builder: PyTorchの各OS/CUDAバージョンなどに対応したビルドシステムに関するリポジトリ。
  • pytorch/serve: モデルデプロイのためのライブラリ(TorchServe)。

これらの関連リポジトリも、PyTorchを総合的に活用する上で重要ですが、本記事では特にコアライブラリであるpytorch/pytorchリポジトリに焦点を当てて解説を進めます。

見るべき主要なセクションの詳細解説

pytorch/pytorchリポジトリにアクセスしたら、具体的にどの部分を見れば良いのでしょうか?ここでは、特に注目すべき主要なセクションと、それぞれの活用法を詳細に解説します。

A. README.md とトップレベルのファイル

リポジトリのトップページに表示されるREADME.mdファイルは、そのプロジェクトの「顔」であり、最も基本的な情報源です。PyTorchリポジトリのREADME.mdも例外ではありません。

なぜ見るべきか?

  • プロジェクト概要: PyTorchが何であるか、主要な機能、そしてなぜそれを使うべきかといったプロジェクトの目的と価値提案が簡潔にまとめられています。
  • インストール方法: 最も標準的なPyTorchのインストール方法(condaやpip)が記載されています。
  • ビルド方法: ソースコードからPyTorchをビルドしたい場合の手順が詳細に説明されています。特定の開発環境を構築したり、最新の開発版を使いたい場合に必須の情報です。
  • コントリビューションガイドへのリンク: プロジェクトに貢献したいと考えたときに最初に参照すべきCONTRIBUTING.mdファイルへのリンクがあります。
  • 関連情報へのリンク: 公式ウェブサイト、ドキュメント、チュートリアル、フォーラム、Slackチャンネルなど、PyTorchに関する他の重要なリソースへのリンクが集められています。
  • 最新ビルドステータス: 多くの場合、各種環境でのビルドやテストの成功/失敗を示すバッジが表示されており、リポジトリの現在の健全性を一目で確認できます。

README.mdだけでなく、トップレベルにある他の重要なファイルも確認しましょう。

  • CONTRIBUTING.md: PyTorchプロジェクトへの貢献方法が詳細に説明されています。どのような種類の貢献が歓迎されるか(バグ修正、新機能、ドキュメント、テスト)、コントリビューションのワークフロー(Issueの立て方、Pull Requestの出し方、コード規約、テストの実行方法など)、署名付きコミットの要件など、コントリビューターにとって必須のガイドラインです。PyTorchの開発プロセスに興味があるなら、必ず読むべきファイルです。
  • CODE_OF_CONDUCT.md: PyTorchコミュニティにおける行動規範が示されています。多様で包括的なコミュニティを維持するためのルールや、ハラスメントがあった場合の報告先などが記載されています。健全なコミュニティ活動のために重要です。
  • LICENSE: PyTorchのライセンス(通常はBSDライセンス)が記載されています。PyTorchを利用したり、コードを再配布したりする際の法的な条件を確認できます。
  • SECURITY.md: セキュリティ上の脆弱性を発見した場合の報告手順が記載されています。

これらのトップレベルファイルは、PyTorchプロジェクトがどのように運営され、どのようにコミュニティと関わっていくべきか、といった基礎情報を提供しています。リポジトリ探索の第一歩として、まずこれらのファイルに目を通すことを強くお勧めします。

B. Issues (イシュー)

GitHubのIssuesセクションは、プロジェクトにおける様々な「問題」や「要望」を管理するための機能です。PyTorchリポジトリのIssuesセクションは、開発者、ユーザー、研究者からの活発な報告や議論が行われる中心的な場所の一つです。

なぜ見るべきか?

  • PyTorchの現状を知る: 現在どのようなバグが存在するのか、どのような機能が不足していると考えられているのかなど、PyTorchの現在の課題を把握できます。
  • 開発の優先順位を推測する: コア開発者がどのIssueにコメントしているか、どのIssueに特定のラベルが付与されているかなどから、開発チームが現在何に注力しているのかを推測できます。
  • 問題解決のヒントを得る: 自分が遭遇したバグが既に報告されていないか検索できます。もし報告されていれば、そのIssueに付いている情報(再現方法、回避策、議論の経緯、修正状況など)が問題解決の大きな手助けになります。
  • コミュニティのニーズを知る: どのような機能がユーザーから要望されているのかを知ることができます。これは、自身がPyTorchを使って開発する上でのトレンドを掴んだり、将来的に貢献したい分野を見つけたりするのに役立ちます。
  • コントリビューションのきっかけを見つける: 特に「Good First Issue」のようなラベルが付いたIssueは、コントリビューションを始めたい初心者向けに、比較的取り組みやすいタスクが示されています。

見るべきポイントと活用のヒント:

PyTorchリポジトリには非常に多くのIssueが開かれています。効率的に情報を見つけるためには、以下の点を意識しましょう。

  1. ラベルを活用する: PyTorchリポジトリでは、Issueに様々なラベルが付与されています。これをフィルタリングに活用しない手はありません。

    • bug: バグ報告。具体的な問題に直面している場合に確認すべきラベルです。
    • feature request: 新機能の要望や提案。PyTorchに今後追加されるかもしれない機能について知りたい場合に。
    • untriaged: まだ開発チームによって内容が確認・分類されていないIssue。最新のIssueを見たい場合に役立ちます。
    • triaged: 開発チームによって確認され、ラベルや担当者が付与されたIssue。
    • priority: high / priority: medium / priority: low: そのIssueの重要度や対応の緊急度を示唆するラベル(必ずしも正式なプライオリティ管理ではない場合もありますが、参考になります)。
    • module: [特定モジュール名]: 例: module: nn, module: optim, module: autograd, module: cuda, module: build, module: docs など。特定のモジュールに関連するIssueに絞り込みたい場合に非常に有用です。自分が使っている機能や興味のある分野のラベルでフィルタリングしましょう。
    • good first issue: 初心者向けのコントリビューションタスク。簡単なバグ修正やドキュメント改善などが含まれることが多いです。コントリビューションの第一歩として探してみましょう。
    • discussion: コード変更を伴わない、より広範な議論や提案。Issueだけでなく、GitHub Discussions機能が使われることもあります。
    • question: 質問。使い方がわからない場合など、PyTorchに関する質問が含まれます。

    GitHubのIssueリストの上部にある “Labels” ドロップダウンメニューから、これらのラベルを選択してフィルタリングできます。複数のラベルを組み合わせて絞り込むことも可能です(例: module: nn かつ bug かつ priority: high)。

  2. キーワードで検索する: 特定のエラーメッセージ、関数名、クラス名、デバイス名(CUDAなど)などのキーワードでIssueを検索できます。自身が遭遇した問題と完全に一致するIssueが見つかるかもしれません。検索バーはIssueリストの上部にあります。

  3. Issueの内容を読む: Issueを開いたら、報告者が提供した情報(再現コード、エラーメッセージ、期待される動作、現在の動作、PyTorchのバージョン、環境情報など)を注意深く読みましょう。これらの情報は、問題を理解し、再現し、解決策を探す上で不可欠です。
  4. コメントを読む: そのIssueに関する議論や進捗状況はコメント欄に記録されます。開発者からの質問、他のユーザーからの追加情報や「私も同じ問題に遭遇しました」といったコメント、解決策の提案、PRへのリンクなどが含まれます。コメントを追うことで、問題がどのように検討され、解決に向けてどのように進んでいるのかを理解できます。
  5. 関連するPull Requestを確認する: Issueが修正された場合、そのIssueに紐づけられたPull Request(後述)があるはずです。Issue内でリンクされていることが多いです。PRを見ることで、具体的にどのようなコード変更によって問題が解決されたのかを確認できます。
  6. 新しいIssueを立てる前に検索する: もし新しいバグを発見したり、機能を提案したりしたい場合は、まず同様のIssueが既に存在しないか検索しましょう。重複を避けることは、開発チームとコミュニティ双方の効率化に繋がります。既存のIssueに関連する場合は、そこにコメントを追加するのが適切です。
  7. Issueテンプレートを確認する: 新しいIssueを立てる際には、どのような情報を提供すべきかのテンプレートが表示されます。このテンプレートを確認することで、バグを報告する際に必要な情報を網羅的に含める方法を学べます。

Issuesセクションは、PyTorchが「生きている」プロジェクトであることを実感できる場所です。開発チームやコントリビューターとユーザーが直接対話し、フレームワークを改善していくプロセスがここで行われています。積極的に覗いてみる価値は十分にあります。

C. Pull Requests (プルリクエスト – PR)

GitHubのPull Requests(PR)は、リポジトリへのコード変更を提案し、その変更がプロジェクトのメインライン(通常はmainmasterブランチ)にマージされるまでの議論やレビューのプロセスを行うための機能です。Issueが「何をすべきか」を議論する場である一方、PRは「どのように実装したか」を示す場です。

なぜ見るべきか?

  • PyTorchのコード変更を追跡する: 新機能、バグ修正、パフォーマンス改善など、PyTorchのコードベースに加えられる具体的な変更内容を確認できます。
  • コードレビューのプロセスを学ぶ: コア開発者や他のコントリビューターが、提案されたコードに対してどのような観点からレビューを行っているのかを知ることができます。設計の妥当性、コードの品質、パフォーマンス、テストの網羅性など、プロフェッショナルなコードレビューの基準や議論の進め方を学ぶことができます。
  • 実装の詳細を理解する: 特定の機能がどのように実装されているのかを、実際のコードとそれに対する議論を通じて深く理解できます。公式ドキュメントだけでは分かりにくい内部的な挙動や設計意図を知るヒントが得られます。
  • 開発の進捗状況を把握する: 主要な機能開発やリリースの準備状況を、関連するPRのオープン状況やマージ状況から推測できます。
  • 高品質なコードを書くヒントを得る: PyTorchチームがどのようなコーディング規約を守り、どのようなテストを書いているのかなどを実際のPRから学ぶことができます。これは自身のコード品質向上に繋がります。
  • コントリビューションの参考に: 自分がPRを作成する際に、他のPRの形式やレビューへの対応方法を参考にできます。

見るべきポイントと活用のヒント:

PyTorchリポジトリでは常に多数のPRが開かれています。効率的に有益な情報を見つけるためには、以下の点を意識しましょう。

  1. PRリストをフィルタリングする: Issueと同様に、PRリストもフィルタリングできます。

    • Open / Closed: 現在レビュー中の変更を見たいか、既にマージされた変更を見たいかで絞り込みます。マージされたPRは、その変更がPyTorchの次のバージョンに含まれることを意味します。
    • Author: 特定の開発者やコントリビューターが提案した変更を見たい場合に。
    • Labels: Issueと同じようなラベルがPRにも付与されることがあります(例: module: nn, module: autograd, build, tests, performance など)。興味のある分野のPRに絞り込むのに役立ちます。
    • Draft PRs: まだ作業途中であり、レビューの準備ができていないPR。アイデアの共有や早期フィードバックのために立てられることがあります。
  2. PRのタイトルと説明を読む: PRのタイトルは変更内容を簡潔に表しています。説明欄には、そのPRが解決するIssue(リンクされていることが多い)、変更の目的、具体的な変更内容の概要、なぜそのように実装したのかの理由、テスト方法などが記載されています。まずここでPRの全体像を把握しましょう。

  3. “Files changed” タブでコードを見る: PRの最も重要な部分は、このタブにある実際のコード変更です。追加されたコードは緑色、削除されたコードは赤色で表示されます。コードを読むことで、具体的な実装方法や変更された箇所が分かります。特定の機能の実装を知りたい場合は、関連しそうなファイルへの変更を探しましょう。
  4. “Conversation” タブで議論を読む: PRに対するレビューコメントやコントリビューター間の議論がここに集まります。これがPyTorchのGitHubリポジトリを見る上で最も学びが多い部分の一つと言えるかもしれません。

    • 質問と回答: 実装に関する疑問点、特定の設計判断の理由などが質問され、それに対する回答がなされます。
    • 改善提案: より効率的な実装方法、コーナーケースの考慮漏れ、コードスタイルの指摘など、具体的な改善提案が行われます。
    • テストの指摘: テストが不足している、テストケースが不適切である、といった指摘が行われます。
    • CI (継続的インテグレーション) の結果: 自動テストの実行結果(ビルド成功/失敗、テスト合格/失敗、パフォーマンスの変化など)に関するコメントやステータスが表示されます。テストが失敗している場合は、なぜ失敗したのか、どのように修正されたのかの議論が行われます。
    • 承認とマージ: レビュー担当者が変更を承認するプロセスや、最終的にメインブランチにマージされるまでのやり取りを見ることができます。

    レビューコメントを読む際には、単に「このコードは間違っている」という指摘だけでなく、「なぜ間違っているのか」「どのように改善すれば良いのか」といった議論の根拠や代替案に注目すると、より深く学ぶことができます。
    5. “Checks” タブでテスト結果を見る: このタブには、CI/CDパイプラインで実行された様々な自動チェック(コードスタイルの確認、静的解析、各種環境でのビルド、ユニットテスト、統合テスト、パフォーマンスベンチマークなど)の結果が表示されます。全てのチェックにパスしなければ、通常そのPRはマージされません。どのようなテストが行われているのか、そしてそのテストがどれだけ厳格であるのかを知ることができます。
    6. クローズされたPRから学ぶ: 既にマージされたPRは、PyTorchのコードベースに加えられた確定的な変更です。これらのPRを遡って読むことで、過去のバージョンの改善点や、開発チームがどのような課題に取り組んできたのかを知ることができます。特に大規模な機能追加やアーキテクチャの変更に関するPRは、PyTorchの進化の歴史を理解する上で貴重な情報源となります。

PRのレビュープロセスは、オープンソースプロジェクトの品質を保つ上で非常に重要です。PyTorchチームは非常に厳格なレビューを行っており、そこでの議論は PyTorch の設計思想やコーディング規約を理解する上で最高の教材となります。自分がコントリビューションする際の参考にすることはもちろん、PyTorchの内部動作への理解を深めるためにも、興味のあるPRをいくつかピックアップして読んでみることをお勧めします。最初は難解に感じるかもしれませんが、慣れるにつれて PyTorch の開発文化や技術的な詳細が見えてくるはずです。

D. Code Structure and Key Directories (コード構造と主要ディレクトリ)

PyTorchのGitHubリポジトリのハイライトは何と言ってもそのソースコードそのものです。前述のIssueやPRは開発プロセスを追うためのものですが、コードを読むことはPyTorchが「どのように動いているのか」という根源的な問いに答えるための唯一の方法です。

なぜ見るべきか?

  • 内部構造の理解: PyTorchの各機能(テンソル演算、自動微分、ニューラルネットワークモジュールなど)がコードレベルでどのように実装されているかを理解できます。
  • 高度なカスタマイズや拡張: PyTorchの既存機能では実現できないことをしたい場合(例: 新しいオペレーションの実装、カスタムバックエンドの追加)、コード構造を理解していることが必須となります。
  • パフォーマンスのボトルネック特定: コードを追うことで、特定の処理がなぜ遅いのか、どこにボトルネックがあるのかを詳細に分析できます。
  • バグの根本原因究明: 遭遇したバグが、ライブラリの内部的な挙動に起因する場合、ソースコードを読むことが問題解決の鍵となります。
  • 学習リソースとして: 高品質なC++やPythonコード、そしてそれらがどのように連携しているのかを学ぶことができます。特に、テンソルの効率的な扱い方、GPUプログラミング(CUDA)、C++/Python間の連携(Pybind11など)といった技術について実践的に学べます。

見るべきポイントと活用のヒント:

リポジトリ内のコードは非常に膨大です。全てを理解しようとするのは現実的ではありません。自身の興味や目的に合わせて、関連するディレクトリやファイルに絞って見ていくのが賢明です。以下に、前述の主要ディレクトリについて、より深く掘り下げて解説します。

  1. torch/ ディレクトリ:

    • これはPyTorchのPythonフロントエンドのコードがある場所です。import torchしたときに利用できるクラスや関数(torch.Tensor, torch.nn.Module, torch.optim.Optimizerなど)の定義や、Python側でのロジック(例: モデルの構築、学習ループ、データローディングの設定)がここにあります。
    • torch/nn/: ニューラルネットワークモジュール(層、損失関数など)の定義。カスタム層を実装したい場合や、既存層のフォワード/バックワードの計算が内部でどうなっているのかを知りたい場合に参照します。
    • torch/optim/: オプティマイザ(SGD, Adamなど)の実装。パラメータ更新のアルゴリズムがどのように記述されているかを確認できます。
    • torch/autograd/: 自動微分に関するPython側のラッパーやユーティリティ関数。バックワード計算の仕組みを知る上で重要ですが、コアな勾配計算ロジックは主にC++側にあります。
    • torch/utils/: データローディング(data/)、分散学習(distributed/)、ONNXエクスポート(onnx/)など、様々なユーティリティ機能。

    PythonコードはC++コードに比べて比較的読みやすい場合が多いです。まずここで、普段使っているAPIのPython側での定義や、それがどのようにC++側の機能(torch._Cなどを介してアクセスされることが多い)を呼び出しているのかを追ってみるのが良いでしょう。

  2. aten/ ディレクトリ:

    • PyTorchのテンソル演算の中核を担う部分です。「A Tensor Library」として、様々なバックエンド(CPU, CUDAなど)上で実行される演算の定義と、多くの場合はバックエンド非依存の基本的な実装が含まれています。
    • aten/src/ATen/: オペレーションの宣言(native_functions.yamlから自動生成されることが多い)、テンソルクラスの基本定義、ディスパッチロジックなど。
    • aten/src/ATen/native/: 多くのオペレーションの「ネイティブ」実装。ここには、バックエンドに依存しない共通実装や、各バックエンド(CPU, CUDA, OpenMPなど)向けの具体的なカーネル実装へのディスパッチを行うコードが含まれます。特定のオペレーション(例: add, mm, conv2d)がC++レベルでどのように定義され、異なるデバイスでどのように実行が振り分けられているのかを理解するにはここが重要です。
    • aten/src/ATen/cuda/ / aten/src/ATen/cpu/ など: 各バックエンド固有のカーネル実装。CUDAカーネル(.cuファイル)や、CPU向けのSIMD命令を使った最適化などが含まれていることがあります。PyTorchがどのようにGPUやCPUの計算能力を最大限に引き出しているのかを知るには、これらの低レベル実装を見る必要があります。

    aten/ ディレクトリはC++で書かれており、PyTorchのパフォーマンスや低レベルな挙動の鍵を握っています。PyTorchの内部構造やテンソル計算の仕組みを深く理解したい場合に、時間をかけて読む価値があります。特に、カスタムオペレーションを実装したい場合は、既存のオペレーションがどのように定義され、バックエンド実装にディスパッチされているのかを参考にする必要があります。

  3. c10/ ディレクトリ:

    • PyTorchとCaffe2で共有される共通基盤ライブラリです。
    • c10/core/: TensorImpl、StorageImplなどのテンソル基盤オブジェクト、データ型(ScalarType)、デバイス型(DeviceType)などの定義。
    • c10/util/: 共通ユーティリティ(エラーハンドリング、型情報など)。
    • c10/cuda/ / c10/cpu/ など: デバイス固有のユーティリティやデータ構造。

    c10/ は PyTorch の低レベルなデータ表現や実行モデルの基盤を理解する上で重要です。例えば、テンソルが内部的にどのようにメモリを管理し、異なるデバイスでどのように表現されているのかを知りたい場合に参照します。

  4. test/ ディレクトリ:

    • PyTorchの各機能に対するテストコードが網羅されています。
    • test/test_torch.py: Pythonフロントエンドの基本的なテスト。様々なテンソル演算やユーティリティ関数のテストケースが含まれます。
    • test/test_nn.py: torch.nnモジュールに関するテスト。各層のフォワード/バックワードの数値的な正確性などがテストされています。
    • test/test_autograd.py: 自動微分に関するテスト。勾配計算の正確性や、様々な演算との組み合わせでのテストが含まれます。
    • test/cpp_extension/: カスタムC++拡張に関するテスト。
    • test/cuda/: CUDA固有の機能に関するテスト。
    • test/custom_op/: カスタムオペレーションに関するテスト。

    テストコードは単にコードの正しさを検証するだけでなく、その機能の正しい使い方や、開発者が想定している振る舞いを知るための素晴らしいリソースです。特定の関数やモジュールを使いたいがドキュメントだけでは理解が難しい場合、その機能に関するテストコードを読むことで、具体的な使用例やエッジケースでの振る舞いを把握できます。また、コントリビューションを行う際には、既存のテストコードを参考に新しいテストケースを書くことが求められます。

  5. docs/ ディレクトリ:

    • PyTorch公式ドキュメントのソースコードがここにあります。多くの場合、reStructuredText (rst) 形式で書かれています。
    • docs/source/: ドキュメントの本体ファイル。
    • docs/source/generated/: APIドキュメントなど、コードから自動生成される部分のソースファイル(またはその設定ファイル)。
    • docs/source/notes/: リリースノートなどの情報。

    ドキュメントの記述に貢献したい場合はここを見ます。また、公式ドキュメントで特定の関数の説明が曖昧だと感じた場合、その関数のドキュメントソースを読むことで、元の記述の意図や、他の情報源(コードやIssue)へのリンクを見つけることができるかもしれません。

コードを読む際のヒント:

  • GitHubのコードナビゲーション機能を使う: GitHubはコード中の関数定義や変数宣言へのリンクを自動で生成してくれます。これを利用すると、コード中の未知の要素がどこで定義されているのかを簡単に追うことができます。
  • 特定のコミットやタグを見る: mainブランチは常に最新の開発版であり、不安定な場合があります。特定のリリースバージョン(例: v1.13.1, v2.0.0)のコードを見たい場合は、リポジトリページ上部のブランチ/タグセレクターからそのタグを選択しましょう。公式リリースされた安定版のコードを読むのがおすすめです。
  • 関連するIssueやPRと合わせて読む: コードの変更内容だけを見ても、その変更が行われた背景や目的が分からない場合があります。関連するIssueやPRの説明、議論を合わせて読むことで、コード変更の意図をより深く理解できます。特に、ある機能がなぜ特定の設計になっているのかを知りたい場合は、その機能が実装されたPRの議論が非常に参考になります。
  • ビルド方法を理解する: PyTorchのビルドシステム(CMake, setup.py)は、コードがどのようにコンパイルされ、どのファイルが含まれるかを定義しています。特定の機能がビルド時にどのように有効/無効になるのかなどを理解するには、CMakeLists.txtsetup.pyを見ると良いでしょう。
  • デバッガーを活用する: 実際にPyTorchをソースからビルドしてデバッガー(GDB, PDBなど)をアタッチし、コードの実行をステップ実行してみることは、コードの理解を飛躍的に深めます。特にC++バックエンドの動作を理解したい場合に有効です。

PyTorchのコードベースは非常に大規模で複雑ですが、一つずつ読み解いていくことで、その精巧な設計と強力な機能がどのように実現されているのかが見えてきます。最初は小さな機能や、自分が普段よく使うAPIに関連するコードから読み始めるのが良いでしょう。

E. Discussions (ディスカッション)

GitHub Discussionsは、プロジェクトに関するよりオープンエンドで非同期的な議論を行うための機能です。Issueが特定のバグや機能要望といった具体的な「問題」を中心に議論するのに対し、Discussionsはより広範なトピック、アイデア、Q&A、ロードマップに関する意見交換などに利用されます。

なぜ見るべきか?

  • PyTorchの将来や方向性に関する議論を知る: 将来的に追加される可能性のある大きな機能、アーキテクチャの変更、ロードマップに関する提案などが議論されることがあります。PyTorchの進化の方向性に関心がある場合に重要です。
  • コミュニティのアイデアや提案に触れる: ユーザーやコントリビューターからの斬新なアイデアや改善提案が投稿されます。Issueにするほど具体的ではないが、議論の価値があるトピックが集まります。
  • Q&Aから学ぶ: PyTorchに関する質問とその回答が多く投稿されています。自分が疑問に思っていることと同じ質問が見つかるかもしれません。他のユーザーの質問や回答を読むことで、PyTorchの様々な側面について学ぶことができます。
  • よりカジュアルなコミュニケーション: Issueよりもフォーマルでない雰囲気で、PyTorchに関する様々な話題について議論できます。
  • コントリビューションの足がかりに: 新しいアイデアについて議論したり、他の人の質問に答えたりすることで、コミュニティに貢献できます。また、議論されているアイデアを具体化する形でコントリビューションの機会を見つけることもあります。

見るべきポイントと活用のヒント:

PyTorchリポジトリのDiscussionsセクションには、いくつかのカテゴリーが設けられています。

  • Ideas (アイデア): 新しい機能や改善提案に関する議論。
  • Q&A: PyTorchの使い方、エラー、パフォーマンスに関する質問と回答。
  • General (一般): カテゴリーに属さない一般的な話題、アナウンス、コミュニティに関する議論など。
  • Roadmap (ロードマップ): PyTorchの将来的な開発計画や優先順位に関する議論。

活用のヒント:

  • カテゴリーを絞って見る: 自身の興味に合わせてカテゴリーを選択しましょう。
  • 人気のトピックや最近の活動を見る: 注目されている議論や、活発なやり取りが行われているトピックを確認できます。
  • キーワードで検索する: 特定の機能や問題に関する議論を探す際に検索機能を活用しましょう。
  • 質問を投稿する: ドキュメントや他の情報源を見ても解決しない疑問がある場合は、Q&Aカテゴリーで質問を投稿してみましょう。他のコミュニティメンバーや開発者が助けてくれる可能性があります。
  • 議論に参加する: 興味のあるアイデアや議論があれば、積極的にコメントしてみましょう。建設的な意見や追加情報を提供することは、コミュニティへの貢献になります。

Discussionsは、GitHubの新しい機能であり、プロジェクトによってはまだIssueが議論の中心である場合もありますが、PyTorchコミュニティではIssuesとDiscussionsが使い分けられ、活発に活用されています。Issueにするほど具体的に落とし込めていないアイデアがある場合や、特定の機能に関するより広範な意見交換をしたい場合に、Discussionsは非常に適した場となります。

F. Wiki

GitHubのWiki機能は、リポジトリに関する補足的なドキュメントや情報をまとめるために利用されます。PyTorchリポジトリのWikiには、コードベースに関する詳細な情報や開発者向けのガイドラインなどが含まれていることがあります。

なぜ見るべきか?

  • 開発者向け詳細情報: docs/ ディレクトリに含まれる公式ドキュメントとは異なり、より内部構造に踏み込んだ情報や、開発環境のセットアップに関する詳細な手順、デザインノートなどが掲載されていることがあります。
  • 歴史的な経緯や設計判断: 特定の機能やアーキテクチャがなぜそのように設計されたのかといった、IssueやPRの議論だけでは追いきれない背景情報がまとめられている場合があります。
  • 非公開情報に近いが公開されている情報: コア開発者間のやり取りや、まだ公式ドキュメントには反映されていないが開発者にとっては重要な情報がここに置かれていることがあります。

見るべきポイントと活用のヒント:

PyTorchリポジトリのWikiは、必ずしも全ての情報が網羅されているわけではありませんが、特定のトピックについて深く知りたい場合に掘り出し物が見つかることがあります。

  • サイドバーのページリストを確認する: Wikiのトップページに表示されるページリストや、サイドバーにあるナビゲーションをチェックし、どのようなトピックのページが存在するかを確認します。
  • キーワードで検索する: GitHubリポジトリ全体の検索機能でWikiも検索対象に含めることができます。探している情報に関連するキーワードで検索してみましょう。
  • CONTRIBUTING.mddocs/ と合わせて読む: Wikiの情報は、他の公式ドキュメントやコントリビューションガイドを補完する形で利用されることが多いです。

Wikiは常に最新の情報に保たれているとは限りませんが、特定の分野について深く探求する際に、貴重な補助情報を提供してくれる可能性があります。

G. Project Boards (プロジェクトボード)

GitHub Projects機能は、IssueやPull Requestをカンバン方式のようなボード上で管理し、開発タスクの進捗状況を可視化するためのツールです。

なぜ見るべきか?

  • 開発タスクの進捗状況を追跡する: 特定のリリース、主要な機能開発、または特定のサブチームの作業がどのように進んでいるのかを、視覚的に把握できます。
  • 開発の優先順位や計画を知る: ボード上でタスクがどのように整理されているかを見ることで、開発チームが何に注力しているのか、次に何が来るのかといった計画の一端を垣間見ることができます。
  • 関連タスクをまとめて見る: 特定の大きな目標(例: 「2.0リリースに向けたX機能の完成」)に関連する複数のIssueやPRがボード上でグループ化されていることがあります。

見るべきポイントと活用のヒント:

PyTorchリポジトリでは、内部的な開発プロセスに合わせてProject Boardsが利用されている可能性があります。

  • 公開されているプロジェクトボードを探す: リポジトリの「Projects」タブをクリックし、公開されているプロジェクトボードがあるか確認します。
  • ボードの列(カラム)の意味を理解する: 通常、列はタスクの状態(例: Todo, In Progress, Reviewing, Done)を表します。これらの列を追うことで、各タスクがどの段階にあるのかが分かります。
  • 各カード(Issue/PR)の詳細を見る: ボード上の各カードは、通常IssueやPRへのリンクになっています。カードをクリックして、そのタスクの詳細(説明、議論、コード変更)を確認できます。

Project Boardsは内部的なプロジェクト管理ツールとして利用されることが多いですが、公開されている場合は PyTorch の開発がどのように組織され、進められているのかを知るための参考になります。ただし、全ての開発作業がボード上で管理されているわけではない点に注意が必要です。

GitHub以外の公式リソース

PyTorchに関する情報は、GitHubリポジトリだけに存在するわけではありません。公式GitHubリポジトリをより効果的に活用するためにも、PyTorchのエコシステムにおける他の重要な公式リソースについても知っておくことが重要です。

  1. 公式ドキュメントサイト (pytorch.org/docs)

    • これはPyTorchユーザーにとって最も基本的な情報源です。APIリファレンス、様々な概念(テンソル、自動微分、nn.Moduleなど)に関する詳細な説明、そしてチュートリアルが網羅されています。
    • GitHubとの連携: このドキュメントのソースコードは、前述したpytorch/pytorchリポジトリ内のdocs/ディレクトリにあります。つまり、ドキュメントを改善するためのコントリビューションも、GitHubの通常のPRワークフローを通じて行うことができます。また、特定のAPIの説明を読んでいるときに、そのAPIが内部でどのように実装されているのかを知りたい場合は、ドキュメントからGitHubのソースコードへのリンクを辿れることもあります。
  2. 公式ウェブサイト (pytorch.org)

    • PyTorchに関する最新ニュース、ブログ投稿、イベント情報、そしてドキュメントやチュートリアル、関連プロジェクトへのリンクが掲載されています。PyTorchに関する全体的な情報を得るためのポータルサイトです。
  3. PyTorch フォーラム (discuss.pytorch.org)

    • PyTorchに関するユーザー間の質問と回答、一般的な議論のための場です。GitHub Issuesよりもカジュアルな雰囲気で、幅広いレベルのユーザーからの質問が投稿されます。
    • GitHubとの使い分け: バグ報告や具体的な機能要望のように、コード変更に直接繋がる可能性が高い技術的な問題はGitHub Issuesに報告するのが適切です。一方、使い方に関する質問、ベストプラクティスに関する相談、特定のモデル実装に関する議論、一般的なPyTorchの機能に関する疑問などはフォーラムに投稿するのが適しています。
  4. PyTorch Tutorials (pytorch/tutorials GitHubリポジトリ および pytorch.org/tutorials)

    • PyTorchの様々な機能の使い方を学べる実践的なチュートリアル集です。画像分類、RNN、GANs、TorchScript、分散学習など、幅広いトピックをカバーしています。
    • GitHubとの連携: チュートリアルのソースコードは独立したpytorch/tutorialsリポジトリで管理されており、改善提案やバグ修正のPRを出すことができます。

これらのリソースは、それぞれ異なる役割を持ちながら、PyTorchエコシステムを形成しています。公式GitHubリポジトリは開発の最前線ですが、これらの他のリソースと連携して利用することで、PyTorchに関するより包括的な情報を得ることができます。例えば、ドキュメントで使い方を学び、GitHubリポジトリで内部実装を確認し、フォーラムで他のユーザーと議論するといった使い分けが考えられます。

PyTorch GitHubリポジトリへのコントリビューション

PyTorchはオープンソースプロジェクトであり、その発展はコミュニティからのコントリビューションによって支えられています。GitHubリポジトリを深く探求することは、コントリビューションの機会を見つけ、実際に貢献するための準備として非常に重要です。

コントリビューションの種類:

PyTorchへのコントリビューションは、コードの追加や修正だけではありません。様々な形でプロジェクトに貢献できます。

  • バグ修正: 遭遇したバグを修正するコードを書く。
  • 新機能の実装: IssueやDiscussionで提案・議論された新機能を実装する。
  • 既存機能の改善: パフォーマンス最適化、メモリ使用量の削減、コードの可読性向上など。
  • ドキュメントの改善: 説明が分かりにくい部分を明確にする、不足している情報を追加する、誤字脱字を修正するなど。
  • テストの追加: 新しい機能に対するテストケースを追加する、既存機能の網羅性を高めるテストを追加する。
  • Issueへのコメント: バグの再現方法に関する情報を提供したり、他のユーザーの質問に答えたり、議論に参加したりする。
  • レビューへの参加: 開かれているPull Requestのコードを読んでフィードバックを提供する(ただし、PyTorchのような大規模プロジェクトでは、レビュー担当者はある程度経験のある開発者に限られることが多いかもしれません)。

コントリビューションの一般的な流れ:

PyTorchのような大規模なオープンソースプロジェクトへのコントリビューションには、いくつかのステップがあります。CONTRIBUTING.md に詳細なガイドラインが記載されていますが、一般的な流れは以下のようになります。

  1. 貢献したいことを見つける: Issueリストを眺めて「Good First Issue」を探したり、自身が遭遇したバグを修正しようとしたり、フォーラムやDiscussionで議論されているアイデアを具体化しようとしたりします。貢献するタスクを明確にすることが第一歩です。
  2. 既存のIssueやDiscussionを確認する: 貢献したい内容が既に議論されていないか、他の人が取り組んでいないかを確認します。関連するIssueやDiscussionがあれば、そこにコメントして「このタスクに取り組みたい」という意思表示をすることが推奨されます。これにより、重複作業を防ぎ、開発チームからのフィードバックを得やすくなります。
  3. リポジトリをForkする: PyTorchリポジトリを自分のGitHubアカウントにForkします。これにより、自分自身の変更を加えられるリポジトリのコピーが手に入ります。
  4. ローカルにCloneし、ブランチを作成する: Forkしたリポジトリを自分のコンピュータにCloneし、作業用の新しいブランチを作成します。メインブランチ(main)で直接作業しないのが慣習です。ブランチ名はその作業内容が分かるような名前にしましょう(例: fix/nn-layer-bug, feat/new-optimizer)。
  5. コードを書く: 選択したタスクに取り組み、コードの変更、追加、削除などを行います。
  6. テストを書く・実行する: 加えた変更に対するテストを書きます。バグ修正であれば、そのバグを再現するテストケースを追加し、修正後にそのテストがパスすることを確認します。新機能であれば、その機能が正しく動作することを検証するテストを追加します。PyTorchのテストスイートを実行し、自身の変更によって既存のテストが失敗していないことを確認することも非常に重要です。CONTRIBUTING.mdにテストの実行方法が記載されています。
  7. 変更をコミットする: コードの変更をコミットします。コミットメッセージは、何を変更したのか、なぜ変更したのかを簡潔かつ明確に記述する必要があります。多くのオープンソースプロジェクトでは、特定のコミットメッセージの形式が推奨されています(例: 最初の行で変更の要約、その後に詳細を記述)。PyTorchでは、署名付きコミット(Signed-off-by line)が求められる場合があります。
  8. リモートリポジトリにPushする: 作成したブランチのコミットを、自身のForkしたGitHubリポジトリにPushします。
  9. Pull Request (PR) を作成する: 自身のForkしたリポジトリから、本家のpytorch/pytorchリポジトリのmainブランチなど、適切なブランチに対してPull Requestを作成します。
  10. PRの説明を記述する: PRを作成する際には、そのPRが解決するIssue(もしあれば)、変更の概要、具体的な変更内容、なぜそのように実装したのか、テスト方法などを詳細に記述します。PyTorchではPR作成時にテンプレートが表示されるので、それに沿って情報を入力します。
  11. レビューを受ける: 作成したPRは、PyTorchのメンテナーや他のコントリビューターによってレビューされます。レビュー担当者からコメントや変更要求(”Request changes”)が来るので、それに対応します。レビュープロセスでは、コードの品質、設計の妥当性、パフォーマンス、テストの網羅性など、様々な観点からフィードバックが提供されます。レビュー担当者との建設的なコミュニケーションが重要です。
  12. CIテストがパスすることを確認する: PRが作成されると、自動的にGitHub ActionsなどのCIシステムが起動し、様々な環境でのビルドやテストが実行されます。これらのテストが全てパスすることを確認する必要があります。テストが失敗した場合は、原因を特定し、コードを修正して再度Pushします。
  13. マージされる: レビュー担当者全員の承認が得られ、全てのCIテストがパスすれば、そのPRは本家のリポジトリにマージされます。これであなたの貢献がPyTorchに取り込まれたことになります!

PyTorchのような大規模プロジェクトへの初めてのコントリビューションは、少し敷居が高く感じられるかもしれません。しかし、「Good First Issue」から始める、ドキュメントの改善から取り組む、あるいは既存のIssueやPRに建設的なコメントを残すといった、比較的小さなステップから始めることができます。そして何よりも重要なのは、プロジェクトのガイドライン(特にCONTRIBUTING.md)をよく読み、コミュニティの文化を尊重することです。

GitHubリポジトリを見ることは、まさにこのコントリビューションプロセス全体を学ぶための最良の方法です。他の人がどのようにPRを作成し、レビューを受け、テストに対応しているのかを見ることで、自分がコントリビューションする際の参考にできます。

まとめ

本記事では、PyTorchの公式GitHubリポジトリ(pytorch/pytorch)を徹底的に解説し、特に注目すべきポイントとその活用法について詳細に説明しました。

PyTorchのGitHubリポジトリは、単なるソースコードの保管場所ではありません。そこは、PyTorchという巨大なオープンソースプロジェクトが呼吸し、成長している心臓部です。開発チームと世界中のコントリビューターが協力し、日々コードが追加・変更され、バグが修正され、新機能が議論されています。

リポジトリ内の各セクション(README.md、Issues、Pull Requests、コード構造、Discussions、Wiki、Project Boards)は、それぞれ異なる種類の情報を提供しています。

  • README.md やトップレベルファイル は、プロジェクトの基本的な情報、ビルド方法、そして貢献するためのガイドラインを提供します。
  • Issues は、PyTorchの現在の課題(バグ、機能要望)やコミュニティのニーズを知るための最前線です。
  • Pull Requests は、PyTorchに加えられる具体的なコード変更と、それに対する詳細な技術的議論、コードレビュープロセスを追跡するための場所です。ここを読むことは、PyTorchの設計思想や高品質なコードを書くことについて学ぶ上で非常に価値があります。
  • コード構造(特に torch/, aten/, c10/, test/ ディレクトリ) は、PyTorchが内部でどのように動作しているのか、そのメカニズムをコードレベルで理解するための核となる部分です。自身のPyTorchスキルを次のレベルに引き上げたい場合に不可欠な情報源です。
  • Discussions は、より広範なアイデア、ロードマップ、Q&Aなど、Issueよりもカジュアルでオープンな議論の場です。
  • WikiProject Boards は、補足的な開発者向け情報やプロジェクト管理の状況を知るための情報源となります。

これらの情報源をGitHub外の公式ドキュメント、チュートリアル、フォーラムといったリソースと組み合わせて活用することで、PyTorchに関する知識と理解を飛躍的に深めることができます。

PyTorchのGitHubリポジトリを探検することは、時に圧倒されるほど情報量が多いと感じるかもしれません。しかし、自身の興味や目的に合わせて特定のセクションやファイルに焦点を絞り、少しずつ慣れていくのが良いアプローチです。特定の機能の実装を知りたい場合はそのコードを、遭遇したバグの原因を知りたい場合は関連IssueやPRを、新機能のアイデアがある場合はDiscussionを、といったように、目的に応じて参照する場所を変えましょう。

そして、もしPyTorchコミュニティに貢献したいという気持ちが芽生えたなら、GitHubリポジトリはコントリビューション活動の中心地となります。CONTRIBUTING.md を読み、IssueやDiscussionで適切なコミュニケーションをとり、Pull Requestを通じてコードを提案するという一連のプロセスを学ぶことができます。PyTorchのような世界的なプロジェクトに貢献することは、自身のスキル向上だけでなく、広大な開発者コミュニティの一員となる素晴らしい経験です。

PyTorchはこれからも進化を続けます。その最先端の動向を追い、内部構造を理解し、そしてもしかすると自身の貢献を通じてその発展に関わるためにも、PyTorchの公式GitHubリポジトリは私たちにとって開かれた最高の学習リソースであり、コミュニティへの扉なのです。

さあ、恐れずにgithub.com/pytorch/pytorchのページを開き、PyTorchの深淵な世界への探検を始めてみましょう。きっと、あなたのPyTorchとの関わり方が変わるはずです。


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール