dask下面是一個使用and的可運行代碼片段cupy,我遇到了問題。我在激活了 GPU 的 Google Colab 上運行它。
基本上我的問題是,A和At是對 RAM 來說太大的陣列,這就是我使用Dask. 在這些對于 RAM 陣列來說太大的情況下,我運行操作,但我想獲得AtW1[:,k](作為一個cupy陣列)而不破壞我的 RAM 或 GPU 記憶體,因為我需要這個值來進行進一步的操作。我怎樣才能做到這一點?
import dask.array as da
import cupy as cp
from dask_cuda import LocalCUDACluster
from dask.distributed import Client
cluster = LocalCUDACluster()
client = Client(cluster)
n_topics = 10
n_terms = 10000
n_docs = 250000
k = 0
A = da.zeros_like(cp.zeros(1), shape=(n_terms,n_docs), chunks=(1,n_docs))
At = A.transpose().rechunk((10, n_terms))
n_row = A.shape[0]
n_col = A.shape[1]
W1 = cp.random.random((n_row, n_topics))
H = cp.random.random((n_col, n_topics))
W1tW1 = W1.T.dot(W1)
# The problem starts here: i want to get AtW1[:,k] as a cupy array without blowing my RAM
AtW1 = da.dot(At, W1).rechunk((n_docs, 1))
AtW1 = AtW1.persist()
val = AtW1[:,k].compute()
val
編輯:另一個有同樣問題的例子。如何在不更改第一部分的情況下實作計算?第一部分的變數就在那里,所以陣列的維度很清楚,示例是可運行的。
import cupy as cp
import dask.array as da
from dask.array.linalg import norm
from dask_cuda import LocalCUDACluster
from dask.distributed import Client
cluster = LocalCUDACluster()
client = Client(cluster)
####### These are given and cannot be changed #######
big = 250000
small = 10000
full = da.full_like(cp.full(1, 2.0), fill_value=2.0, shape=(small,big), chunks=(1,big))
a = cp.random.random((small, 10))
b = cp.transpose(cp.random.random((big, 10)))
###### How can i make this work? #######
ab = da.dot(da.from_array(a), da.from_array(b))
subtracted = full - ab
normalized = norm(subtracted, ord='fro')
val = normalized.compute()
uj5u.com熱心網友回復:
雖然重新分塊的想法在紙面上很有意義,但實際上重新分塊需要非常小心,因為它只能重塑原則上可以被阻止的作業。
例如,比較以下兩種方法:
A = da.zeros_like(cp.zeros(1), shape=(n_terms,n_docs), chunks=(1,n_docs))
At = A.transpose().rechunk((1, n_terms))
At_version2 = da.zeros_like(cp.zeros(1), shape=(n_docs, n_terms), chunks=(1,n_terms))
當請求At[0,:]的作業量dask將比本來要完成的作業量要大得多At_version2[0,:]。為什么?因為原始資料At將在 的塊中定義(1,n_docs),所以要生成轉置的第一行,dask必須A在每一行評估原始陣列。
使用此邏輯,最好確保您的資料以確實與獲得最終結果所需的塊乘法兼容的形狀提供。這將導致更少的任務和更低的記憶體需求,因為現在只需將資料的子集保存在記憶體中。
這是快速計算的代碼的修改版本:
import dask.array as da
import cupy as cp
from dask_cuda import LocalCUDACluster
from dask.distributed import Client
cluster = LocalCUDACluster()
client = Client(cluster)
n_topics = 10
n_terms = 10000
n_docs = 250000
k = 0
At_v2 = da.zeros_like(cp.zeros(1), shape=(n_docs, n_terms), chunks=(1000,n_terms))
W1 = cp.random.random((n_terms, n_topics))
result = da.dot(At_v2, W1)[:,0].compute()
另請注意,運行.persist會將陣列保留在記憶體中,因此如果記憶體是一個約束,您可能不想用.persist.
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/410488.html
標籤:
