

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon EMR on EKS での RAPIDS Accelerator for Apache Spark の使用
<a name="tutorial-spark-rapids"></a>

Amazon EMR on EKS では、Nvidia RAPIDS Accelerator for Apache Spark のジョブを実行できます。このチュートリアルでは、EC2 グラフィック処理ユニット (GPU) インスタンスタイプで RAPIDS を使用して Spark ジョブを実行する方法について説明します。このチュートリアルでは、次のバージョンを使用します。
+ Amazon EMR on EKS リリースバージョン 6.9.0 以降
+ Apache Spark 3.x

[Nvidia RAPIDS Accelerator for Apache Spark](https://docs.nvidia.com/spark-rapids/user-guide/latest/overview.html) プラグインを使用すると、Amazon EC2 GPU インスタンスタイプで Spark を高速化できます。これらのテクノロジーを併用すると、コードを変更しなくてもデータサイエンスパイプラインを高速化できます。これにより、データ処理とモデルトレーニングに必要な実行時間が短縮されます。短時間で多くのことができるようになるので、インフラストラクチャのコストを抑えることができます。

開始する前に、次のリソースが使用可能であることを確認してください。
+ Amazon EMR on EKS 仮想クラスター
+ GPU 対応のノードグループを備えた Amazon EKS クラスター

Amazon EKS 仮想クラスターは、Amazon EKS クラスター上の Kubernetes 名前空間への登録ハンドルであり、Amazon EMR on EKS によって管理されます。このハンドルにより、Amazon EMR は Kubernetes 名前空間をジョブの実行先として使用できます。仮想クラスターをセットアップする方法の詳細については、このガイドの「[Amazon EMR on EKS のセットアップ](setting-up.md)」を参照してください。

ノードグループに GPU インスタンスを含めて、Amazon EKS 仮想クラスターを設定する必要があります。ノードには、Nvidia デバイスプラグインを設定する必要があります。詳細については、「[Managed node groups](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html)」を参照してください。

GPU 対応のノードグループを追加するように Amazon EKS クラスターを設定するには、次の手順を実行します。

**GPU 対応のノードグループを追加するには**

1. 次の [create-nodegroup](https://docs.aws.amazon.com/cli/latest/reference/eks/create-nodegroup.html) コマンドで GPU 対応のノードグループを作成します。Amazon EKS クラスターに合わせて適切なパラメータに置き換えてください。インスタンスタイプは、P4、P3、G5、G4dn など Spark RAPIDS をサポートするものを使用します。

   ```
   aws eks create-nodegroup \
    --cluster-name EKS_CLUSTER_NAME \
    --nodegroup-name NODEGROUP_NAME \
    --scaling-config minSize=0,maxSize=5,desiredSize=2 CHOOSE_APPROPRIATELY \
    --ami-type AL2_x86_64_GPU \
    --node-role NODE_ROLE \
    --subnets SUBNETS_SPACE_DELIMITED  \
    --remote-access ec2SshKey= SSH_KEY \
    --instance-types GPU_INSTANCE_TYPE \
    --disk-size DISK_SIZE \
    --region AWS_REGION
   ```

1. クラスターに Nvidia デバイスプラグインをインストールすると、クラスターの各ノードに多数の GPU を出力し、クラスターで GPU 対応のコンテナを実行できます。次のコードを実行して、このプラグインをインストールします。

   ```
   kubectl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml
   ```

1. クラスターの各ノードで使用可能な GPU の数を確認するには、次のコマンドを実行します。

   ```
   kubectl get nodes  "-o=custom-columns=NAME:.metadata.name,GPU:.status.allocatable.nvidia\.com/gpu"
   ```

**Spark RAPIDS ジョブを実行するには**

1. Amazon EMR on EKS クラスターに Spark RAPIDS ジョブを送信します。ジョブを開始するには、次のコードに示したようなコマンドを使用します。ジョブを初めて実行する場合、イメージをダウンロードしてノードにキャッシュするまでに数分かかる場合があります。

   ```
   aws emr-containers start-job-run \
   --virtual-cluster-id VIRTUAL_CLUSTER_ID \
   --execution-role-arn JOB_EXECUTION_ROLE \
   --release-label emr-6.9.0-spark-rapids-latest \
   --job-driver '{"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar","entryPointArguments":  ["10000"], "sparkSubmitParameters":"--class org.apache.spark.examples.SparkPi "}}' \
   ---configuration-overrides '{"applicationConfiguration": [{"classification": "spark-defaults","properties": {"spark.executor.instances": "2","spark.executor.memory": "2G"}}],"monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "LOG_GROUP _NAME"},"s3MonitoringConfiguration": {"logUri": "LOG_GROUP_STREAM"}}}'
   ```

1. Spark RAPIDS Accelerator が使用可能であることを確認するには、Spark ドライバーログをチェックします。このログは、CloudWatch か、または `start-job-run` コマンドを実行するときに指定した S3 の場所に保存されています。次の例は、一般的にログの各行がどのように表示されるかを示しています。

   ```
   22/11/15 00:12:44 INFO RapidsPluginUtils: RAPIDS Accelerator build: {version=22.08.0-amzn-0, user=release, url=, date=2022-11-03T03:32:45Z, revision=, cudf_version=22.08.0, branch=}
   22/11/15 00:12:44 INFO RapidsPluginUtils: RAPIDS Accelerator JNI build: {version=22.08.0, user=, url=https://github.com/NVIDIA/spark-rapids-jni.git, date=2022-08-18T04:14:34Z, revision=a1b23cd_sample, branch=HEAD}
   22/11/15 00:12:44 INFO RapidsPluginUtils: cudf build: {version=22.08.0, user=, url=https://github.com/rapidsai/cudf.git, date=2022-08-18T04:14:34Z, revision=a1b23ce_sample, branch=HEAD}
   22/11/15 00:12:44 WARN RapidsPluginUtils: RAPIDS Accelerator 22.08.0-amzn-0 using cudf 22.08.0.
   22/11/15 00:12:44 WARN RapidsPluginUtils: spark.rapids.sql.multiThreadedRead.numThreads is set to 20.
   22/11/15 00:12:44 WARN RapidsPluginUtils: RAPIDS Accelerator is enabled, to disable GPU support set `spark.rapids.sql.enabled` to false.
   22/11/15 00:12:44 WARN RapidsPluginUtils: spark.rapids.sql.explain is set to `NOT_ON_GPU`. Set it to 'NONE' to suppress the diagnostics logging about the query placement on the GPU.
   ```

1. GPU で実行される操作を確認するには、次の手順を実行して、他のログも記録されるようにします。「`spark.rapids.sql.explain : ALL`」の設定をメモしておきます。

   ```
   aws emr-containers start-job-run \
   --virtual-cluster-id VIRTUAL_CLUSTER_ID \
   --execution-role-arn JOB_EXECUTION_ROLE \
   --release-label emr-6.9.0-spark-rapids-latest \
   --job-driver '{"sparkSubmitJobDriver": {"entryPoint": "local:///usr/lib/spark/examples/jars/spark-examples.jar","entryPointArguments":  ["10000"], "sparkSubmitParameters":"--class org.apache.spark.examples.SparkPi "}}' \
   ---configuration-overrides '{"applicationConfiguration": [{"classification": "spark-defaults","properties": {"spark.rapids.sql.explain":"ALL","spark.executor.instances": "2","spark.executor.memory": "2G"}}],"monitoringConfiguration": {"cloudWatchMonitoringConfiguration": {"logGroupName": "LOG_GROUP_NAME"},"s3MonitoringConfiguration": {"logUri": "LOG_GROUP_STREAM"}}}'
   ```

   前掲のコマンドは、GPU を使用するジョブの一例です。その出力は、次の例のようになります。以下を参考に出力内容を理解してください。
   + `*` — GPU で動作する操作を示します。
   + `!` — GPU で実行できない操作を示します。
   + `@` — GPU で動作するものの、GPU で実行できないプラン内にあるため実行できない操作を示します。

   ```
    22/11/15 01:22:58 INFO GpuOverrides: Plan conversion to the GPU took 118.64 ms
    22/11/15 01:22:58 INFO GpuOverrides: Plan conversion to the GPU took 4.20 ms
    22/11/15 01:22:58 INFO GpuOverrides: GPU plan transition optimization took 8.37 ms
    22/11/15 01:22:59 WARN GpuOverrides:
       *Exec <ProjectExec> will run on GPU
         *Expression <Alias> substring(cast(date#149 as string), 0, 7) AS month#310 will run on GPU
           *Expression <Substring> substring(cast(date#149 as string), 0, 7) will run on GPU
             *Expression <Cast> cast(date#149 as string) will run on GPU
         *Exec <SortExec> will run on GPU
           *Expression <SortOrder> date#149 ASC NULLS FIRST will run on GPU
           *Exec <ShuffleExchangeExec> will run on GPU
             *Partitioning <RangePartitioning> will run on GPU
               *Expression <SortOrder> date#149 ASC NULLS FIRST will run on GPU
             *Exec <UnionExec> will run on GPU
               !Exec <ProjectExec> cannot run on GPU because not all expressions can be replaced
                 @Expression <AttributeReference> customerID#0 could run on GPU
                 @Expression <Alias> Charge AS kind#126 could run on GPU
                   @Expression <Literal> Charge could run on GPU
                 @Expression <AttributeReference> value#129 could run on GPU
                 @Expression <Alias> add_months(2022-11-15, cast(-(cast(_we0#142 as bigint) + last_month#128L) as int)) AS date#149 could run on GPU
                   ! <AddMonths> add_months(2022-11-15, cast(-(cast(_we0#142 as bigint) + last_month#128L) as int)) cannot run on GPU because GPU does not currently support the operator class org.apache.spark.sql.catalyst.expressions.AddMonths
                     @Expression <Literal> 2022-11-15 could run on GPU
                     @Expression <Cast> cast(-(cast(_we0#142 as bigint) + last_month#128L) as int) could run on GPU
                       @Expression <UnaryMinus> -(cast(_we0#142 as bigint) + last_month#128L) could run on GPU
                         @Expression <Add> (cast(_we0#142 as bigint) + last_month#128L) could run on GPU
                           @Expression <Cast> cast(_we0#142 as bigint) could run on GPU
                             @Expression <AttributeReference> _we0#142 could run on GPU
                           @Expression <AttributeReference> last_month#128L could run on GPU
   ```