OpenAI Week 15-16 // The Pile & Azure Blob Storage
For my project, I'm using The Pile, an 800 GB unstructured text dataset scraped from the web, representing a diverse range of modalities from medical papers to code. Such a large dataset is best stored on the cloud. I've written out a guide for how to get set up with The Pile hosted on Azure.
First, create an Azure Blob Storage account. I just followed the instructions and used the default configurations. Meanwhile, on your local or virtual machine, install the az CLI, blobfile, and boostedblob. This will help you easily interact with the files in your Azure storage account.
Now sign in with
az login
and open the link in a web browser to complete the sign in.
When you try to read one of your files from blob storage using blobfile, you'll get an error that you need to set the following environment variables first: AZURE_STORAGE_KEY, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID. You can access these by typing
az ad sp create-for-rbac --name <your name> -o table
which will return a table with items like AppId, DisplayName, Name, Password, and Tenant. It's a bit opaque, but the mapping is
AppID $\rightarrow$ <AZURE_CLIENT_ID>
Name $\rightarrow$ <AZURE_STORAGE_KEY>
Password $\rightarrow$ <AZURE_CLIENT_SECRET>
Tenant $\rightarrow$ <AZURE_TENANT_ID>
so now you can set those environment variables:
import osos.environ['AZURE_STORAGE_KEY'] = <my storage key>
os.environ['AZURE_CLIENT_ID'] = <my client id>
os.environ['AZURE_CLIENT_SECRET'] = <my client secret>
os.environ['AZURE_TENANT_ID'] = <my tenant id>
And there you have it. Last but not least, I'm including my little script for reading off The Pile:
import zstandard
import jsonlines
import simdjson as json
import blobfile as bf parser = json.Parser()
def json_parser(x):
try:
line = parser.parse(x).as_dict()
return line
except ValueError:
return x class PileReader:
def __init__(self, filenames, para_joiner='\n\n'):
if not isinstance(filenames, list):
filenames = [filenames]
self.filenames = filenames
self.para_joiner = para_joiner
def _read_fn(self, filename):
with bf.BlobFile(filename, 'rb') as f:
cctx = zstandard.ZstdDecompressor()
reader_stream = io.BufferedReader(cctx.stream_reader(f))
reader = jsonlines.Reader(reader_stream, loads=json_parser)
for item in reader:
result = dict()
if isinstance(item, str):
result['text'] = item
else:
text = item['text']
if isinstance(text, list):
text = self.para_joiner.join(text)
result['text'] = text
yield result
def __iter__(self):
for filename in self.filenames:
return self._read_fn(filename)
Or you may wish to create a mini-file to work with first, by breaking off a piece of the first training file:
input_file = '/path/to/file/00.jsonl.zst'
output_file = '/path/to/file/00-mini.jsonl.zst'
line_counter = 0
num_lines_to_keep = 2000000 # ~4GB file with bf.BlobFile(input_file, 'rb') as f_in: with bf.BlobFile(output_file, 'wb') as f_out: decompressor = zstandard.ZstdDecompressor()
compressor = zstandard.ZstdCompressor() reader_stream = io.BufferedReader(decompressor.stream_reader(f_in))
reader = jsonlines.Reader(reader_stream, loads=json_parser) writer_stream = io.BufferedWriter(compressor.stream_writer(f_out))
writer = jsonlines.Writer(writer_stream) for line in reader: writer.write(line) line_counter += 1
if line_counter > num_lines_to_keep:
break
Comments
Post a Comment