mirror of
https://github.com/neuml/txtai.git
synced 2026-10-11 21:39:55 +00:00
18 KiB
18 KiB
In [ ]:
%%capture
!pip install git+https://github.com/neuml/txtai#egg=txtai[api,pipeline,workflow] datasetsIn [ ]:
import numpy as np
import torch
# Generate large memory-mapped array
rows, cols = 2000000, 1024
data = np.memmap("data.npy", dtype=np.float32, mode="w+", shape=(rows, cols))
del data
# Open memory-mapped array
data = np.memmap("data.npy", dtype=np.float32, shape=(rows, cols))
# Create tensor
tensor = torch.from_numpy(data).to("cuda:0")
# Apply tanh transform to tensor
torch.tanh(tensor).shape[0;31m---------------------------------------------------------------------------[0m [0;31mRuntimeError[0m Traceback (most recent call last) [0;32m<ipython-input-2-a1fc94fedb69>[0m in [0;36m<module>[0;34m()[0m [1;32m 14[0m [0;34m[0m[0m [1;32m 15[0m [0;31m# Apply tanh transform to tensor[0m[0;34m[0m[0;34m[0m[0;34m[0m[0m [0;32m---> 16[0;31m [0mtorch[0m[0;34m.[0m[0mtanh[0m[0;34m([0m[0mtensor[0m[0;34m)[0m[0;34m.[0m[0mshape[0m[0;34m[0m[0;34m[0m[0m [0m [0;31mRuntimeError[0m: CUDA out of memory. Tried to allocate 7.63 GiB (GPU 0; 11.17 GiB total capacity; 7.63 GiB already allocated; 3.04 GiB free; 7.63 GiB reserved in total by PyTorch) If reserved memory is >> allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF
In [ ]:
!ls -l --block-size=MB data.npy-rw-r--r-- 1 root root 8192MB Dec 6 23:24 data.npy
In [ ]:
def process(x):
print(x.shape)
return torch.tanh(torch.from_numpy(x).to("cuda:0")).cpu().numpy()
# Split into 250,000 rows per call
batch = 250000
count = 0
for x in range(0, len(data), batch):
for row in process(data[x : x + batch]):
count += 1
print(count)(250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) 2000000
In [ ]:
from txtai.workflow import Task, Workflow
# Create workflow with a single task calling process for each batch
task = Task(process)
workflow = Workflow([task], batch)
# Run workflow
count = 0
for row in workflow(data):
count += 1
print(count)(250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) (250000, 1024) 2000000
In [ ]:
from torch import nn
class Model(nn.Module):
def __init__(self):
super().__init__()
self.gelu = nn.ReLU()
self.linear1 = nn.Linear(1024, 512)
self.dropout = nn.Dropout(0.5)
self.norm = nn.LayerNorm(512)
self.linear2 = nn.Linear(512, 1)
def forward(self, inputs):
outputs = self.gelu(inputs)
outputs = self.linear1(outputs)
outputs = self.dropout(outputs)
outputs = self.norm(outputs)
outputs = self.linear2(outputs)
return outputs
model = Model().to("cuda:0")
def process(x):
with torch.no_grad():
outputs = model(torch.from_numpy(x).to("cuda:0")).cpu().numpy()
print(outputs.shape)
return outputs
# Create workflow with a single task calling model for each batch
task = Task(process)
workflow = Workflow([task], batch)
# Run workflow
count = 0
for row in workflow(data):
count += 1
print(count)(250000, 1) (250000, 1) (250000, 1) (250000, 1) (250000, 1) (250000, 1) (250000, 1) (250000, 1) 2000000
In [ ]:
import time
from datasets import load_dataset
from transformers import AutoTokenizer, AutoModelForSequenceClassification
class Tokens:
def __init__(self, texts):
tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased-finetuned-sst-2-english")
tokens = tokenizer(texts, padding=True, return_tensors="pt").to("cuda:0")
self.inputs, self.attention = tokens["input_ids"], tokens["attention_mask"]
def __len__(self):
return len(self.inputs)
def __getitem__(self, value):
return (self.inputs[value], self.attention[value])
class Classify:
def __init__(self, model):
self.model = model
def __call__(self, tokens):
with torch.no_grad():
inputs, attention = tokens
outputs = self.model(input_ids=inputs, attention_mask=attention)
outputs = outputs["logits"]
return outputs
# Load reviews from the rotten tomatoes dataset
ds = load_dataset("rotten_tomatoes")
texts = ds["train"]["text"]
tokens = Tokens(texts)
model1 = AutoModelForSequenceClassification.from_pretrained("M-FAC/bert-tiny-finetuned-sst2")
model1 = model1.to("cuda:0")
model2 = AutoModelForSequenceClassification.from_pretrained("howey/electra-base-sst2")
model2 = model2.to("cuda:0")
model3 = AutoModelForSequenceClassification.from_pretrained("philschmid/MiniLM-L6-H384-uncased-sst2")
model3 = model3.to("cuda:0")
task1 = Task([Classify(model1), Classify(model2), Classify(model3)])
task2 = Task([lambda x: torch.sigmoid(x).mean(axis=1).cpu().numpy()])
workflow = Workflow([task1, task2], 250)
start = time.time()
for x in workflow(tokens):
pass
print(f"Took {time.time() - start} seconds")Using custom data configuration default Reusing dataset rotten_tomatoes_movie_review (/root/.cache/huggingface/datasets/rotten_tomatoes_movie_review/default/1.0.0/40d411e45a6ce3484deed7cc15b82a53dad9a72aafd9f86f8f227134bec5ca46)
Took 84.73194456100464 seconds
In [ ]:
task1 = Task([Classify(model1), Classify(model2), Classify(model3)], concurrency="thread")
task2 = Task([lambda x: torch.sigmoid(x).mean(axis=1).cpu().numpy()])
workflow = Workflow([task1, task2], 250)
start = time.time()
for x in workflow(tokens):
pass
print(f"Took {time.time() - start} seconds")Took 85.21102929115295 seconds