From ce3d4e42c29cd0963d07d2325a6356f620dea8db Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sat, 15 Feb 2025 16:40:29 -0500 Subject: [PATCH 01/40] New Question Set --- README.md | 36 +++- llm/attention-q4.ipynb | 156 +++++++++++++++ llm/embeddings-q2.ipynb | 186 ++++++++++++++++++ template.ipynb | 100 ---------- {e1 => torch/easy/e1}/lin-regression.ipynb | 0 .../easy/e1}/lin-regression_SOLN.ipynb | 0 {e2 => torch/easy/e2}/custom-dataset.ipynb | 0 .../easy/e2}/custom-dataset_SOLN.ipynb | 0 {e2 => torch/easy/e2}/data.csv | 0 {e3 => torch/easy/e3}/custom-activation.ipynb | 0 .../easy/e3}/custom-activation_SOLN.ipynb | 0 {e4 => torch/easy/e4}/custom-loss.ipynb | 0 {e4 => torch/easy/e4}/custom-loss_SOLN.ipynb | 0 {e5 => torch/easy/e5}/custon-DNN.ipynb | 0 {e5 => torch/easy/e5}/custon-DNN_SOLN.ipynb | 0 {e6 => torch/easy/e6}/tensorboard.ipynb | 0 {e6 => torch/easy/e6}/tensorboard_SOLN.ipynb | 0 {e7 => torch/easy/e7}/save_model.ipynb | 0 {e7 => torch/easy/e7}/save_model_SOLN.ipynb | 0 .../hard/h1}/custom-autgrad-function.ipynb | 0 .../h1}/custom-autgrad-function_SOLN.ipynb | 0 {h10 => torch/hard/h10}/xai.ipynb | 0 {h10 => torch/hard/h10}/xai_SOLN.ipynb | 0 {h3 => torch/hard/h3}/transformer.ipynb | 0 {h3 => torch/hard/h3}/transformer_SOLN.ipynb | 0 {h4 => torch/hard/h4}/GAN.ipynb | 0 {h4 => torch/hard/h4}/GAN_SOLN.ipynb | 0 .../hard/h5}/seq-to-seq-with-Attention.ipynb | 0 .../h5}/seq-to-seq-with-Attention_SOLN.ipynb | 0 .../hard/h6}/quantize-language-model.ipynb | 0 .../h6}/quantize-language-model_SOLN.ipynb | 0 {h9 => torch/hard/h9}/cuda-amp.ipynb | 0 {h9 => torch/hard/h9}/cuda-amp_SOLN.ipynb | 0 {m1 => torch/medium/m1}/LSTM.ipynb | 0 {m1 => torch/medium/m1}/LSTM_SOLN.ipynb | 0 {m2 => torch/medium/m2}/CNN.ipynb | 0 {m2 => torch/medium/m2}/CNN_SOLN.ipynb | 0 {m3 => torch/medium/m3}/CNN_ParamInit.ipynb | 0 .../medium/m3}/CNN_ParamInit_SOLN.ipynb | 0 {m4 => torch/medium/m4}/RNN.ipynb | 0 {m4 => torch/medium/m4}/RNN_SOLN.ipynb | 0 {m5 => torch/medium/m5}/augmentation.ipynb | 0 .../medium/m5}/augmentation_SOLN.ipynb | 0 {m6 => torch/medium/m6}/bench.ipynb | 0 {m6 => torch/medium/m6}/bench_SOLN.ipynb | 0 {m7 => torch/medium/m7}/autoencoder.ipynb | 0 .../medium/m7}/autoencoder_SOLN.ipynb | 0 47 files changed, 373 insertions(+), 105 deletions(-) create mode 100644 llm/attention-q4.ipynb create mode 100644 llm/embeddings-q2.ipynb delete mode 100644 template.ipynb rename {e1 => torch/easy/e1}/lin-regression.ipynb (100%) rename {e1 => torch/easy/e1}/lin-regression_SOLN.ipynb (100%) rename {e2 => torch/easy/e2}/custom-dataset.ipynb (100%) rename {e2 => torch/easy/e2}/custom-dataset_SOLN.ipynb (100%) rename {e2 => torch/easy/e2}/data.csv (100%) rename {e3 => torch/easy/e3}/custom-activation.ipynb (100%) rename {e3 => torch/easy/e3}/custom-activation_SOLN.ipynb (100%) rename {e4 => torch/easy/e4}/custom-loss.ipynb (100%) rename {e4 => torch/easy/e4}/custom-loss_SOLN.ipynb (100%) rename {e5 => torch/easy/e5}/custon-DNN.ipynb (100%) rename {e5 => torch/easy/e5}/custon-DNN_SOLN.ipynb (100%) rename {e6 => torch/easy/e6}/tensorboard.ipynb (100%) rename {e6 => torch/easy/e6}/tensorboard_SOLN.ipynb (100%) rename {e7 => torch/easy/e7}/save_model.ipynb (100%) rename {e7 => torch/easy/e7}/save_model_SOLN.ipynb (100%) rename {h1 => torch/hard/h1}/custom-autgrad-function.ipynb (100%) rename {h1 => torch/hard/h1}/custom-autgrad-function_SOLN.ipynb (100%) rename {h10 => torch/hard/h10}/xai.ipynb (100%) rename {h10 => torch/hard/h10}/xai_SOLN.ipynb (100%) rename {h3 => torch/hard/h3}/transformer.ipynb (100%) rename {h3 => torch/hard/h3}/transformer_SOLN.ipynb (100%) rename {h4 => torch/hard/h4}/GAN.ipynb (100%) rename {h4 => torch/hard/h4}/GAN_SOLN.ipynb (100%) rename {h5 => torch/hard/h5}/seq-to-seq-with-Attention.ipynb (100%) rename {h5 => torch/hard/h5}/seq-to-seq-with-Attention_SOLN.ipynb (100%) rename {h6 => torch/hard/h6}/quantize-language-model.ipynb (100%) rename {h6 => torch/hard/h6}/quantize-language-model_SOLN.ipynb (100%) rename {h9 => torch/hard/h9}/cuda-amp.ipynb (100%) rename {h9 => torch/hard/h9}/cuda-amp_SOLN.ipynb (100%) rename {m1 => torch/medium/m1}/LSTM.ipynb (100%) rename {m1 => torch/medium/m1}/LSTM_SOLN.ipynb (100%) rename {m2 => torch/medium/m2}/CNN.ipynb (100%) rename {m2 => torch/medium/m2}/CNN_SOLN.ipynb (100%) rename {m3 => torch/medium/m3}/CNN_ParamInit.ipynb (100%) rename {m3 => torch/medium/m3}/CNN_ParamInit_SOLN.ipynb (100%) rename {m4 => torch/medium/m4}/RNN.ipynb (100%) rename {m4 => torch/medium/m4}/RNN_SOLN.ipynb (100%) rename {m5 => torch/medium/m5}/augmentation.ipynb (100%) rename {m5 => torch/medium/m5}/augmentation_SOLN.ipynb (100%) rename {m6 => torch/medium/m6}/bench.ipynb (100%) rename {m6 => torch/medium/m6}/bench_SOLN.ipynb (100%) rename {m7 => torch/medium/m7}/autoencoder.ipynb (100%) rename {m7 => torch/medium/m7}/autoencoder_SOLN.ipynb (100%) diff --git a/README.md b/README.md index cdd9abf..94cddf0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@
-TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-style challenges, designed to enhance your skills in deep learning and PyTorch. +TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-style challenges, designed to enhance your skills in deep learning and PyTorch. NOW WITH LLMS! ## Table of Contents - [TorchLeet](#torchleet) @@ -20,6 +20,7 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st - [๐ŸŸขEasy](#easy) - [๐ŸŸกMedium](#medium) - [๐Ÿ”ดHard](#hard) + - [LLM Set](#llm-set) - [Getting Started](#getting-started) - [1. Install Dependencies](#1-install-dependencies) - [2. Structure](#2-structure) @@ -37,7 +38,10 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 4. [Implement Custom Loss Function (Huber Loss)](https://github.com/Exorust/TorchLeet/blob/main/e4/custom-loss.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e4/custom-loss_SOLN.ipynb) 5. [Implement a Deep Neural Network](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN_SOLN.ipynb) 6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard_SOLN.ipynb) -7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model_SOLN.ipynb) +7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model_SOLN.ipynb) +8. Implement RMS Norm +9. Implement KL divergence loss +10. Implement Softmax function from scratch ### ๐ŸŸกMedium @@ -61,6 +65,30 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/blob/main/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h9/cuda-amp_SOLN.ipynb) 10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/blob/main/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h10/xai_SOLN.ipynb) + +## LLM Set + +**An all new set of questions to help you understand and implement Large Language Models from scratch. ** + +1. Implement Byte Pair Encoding from Scratch +2. Create an embeddings out of an LLM +3. Implement Predictive Prefill with Speculative Decoding +4. Implement Attention from Scratch +5. Implement KV Cache in Multi-Head Attention from Scratch +6. Implement Sinusoidal Embeddings +7. Implement ROPE Embeddings +8. Implement SmolLM from Scratch +9. Implement Beam Search atop LLM for decoding +10. Implement Top K Sampling atop LLM for decoding +11. Implement Top p Sampling atop LLM for decoding +12. Implement Temperature Sampling atop LLM for decoding +13. Implement LoRA on a layer of an LLM +14. Mix two models to create a mixture of Experts +15. Apply SFT on SmolLM +16. Apply RLHF on SmolLM +17. Implement DPO based RLHF +18. Add continous batching to your LLM + **What's cool? ๐Ÿš€** - **Diverse Questions**: Covers beginner to advanced PyTorch concepts (e.g., tensors, autograd, CNNs, GANs, and more). - **Guided Learning**: Includes incomplete code blocks (`...` and `#TODO`) for hands-on practice along with Answers @@ -84,10 +112,8 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st **Happy Learning! ๐Ÿš€** - - # Contribution -Feel free to contribute by adding new questions or improving existing ones. Ensure that new problems are well-documented and follow the project structure. +Feel free to contribute by adding new questions or improving existing ones. Ensure that new problems are well-documented and follow the project structure. Submit a PR and tag the authors. # Authors diff --git a/llm/attention-q4.ipynb b/llm/attention-q4.ipynb new file mode 100644 index 0000000..3590d80 --- /dev/null +++ b/llm/attention-q4.ipynb @@ -0,0 +1,156 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([1, 3, 3])\n" + ] + } + ], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "q = torch.tensor([[[1.0, 0.5, 0.2], # Query for token 1\n", + " [0.3, 1.2, 0.7], # Query for token 2\n", + " [0.8, 0.1, 1.5]]]) # Query for token 3\n", + "\n", + "k = torch.tensor([[[1.0, 0.2, 0.3], # Key for token 1\n", + " [0.4, 1.5, 0.6], # Key for token 2\n", + " [0.7, 0.1, 1.8]]]) # Key for token 3\n", + "\n", + "v = torch.tensor([[[10.0, 2.0, 3.0], # Value for token 1\n", + " [4.0, 15.0, 6.0], # Value for token 2\n", + " [7.0, 1.0, 18.0]]]) # Value for token 3\n", + "\n", + "print(q.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def scaled_dot_product_attention(q, k, v, mask=None):\n", + " \"\"\"\n", + " Compute the scaled dot-product attention.\n", + " \n", + " Args:\n", + " q: Query tensor of shape (..., seq_len_q, d_k)\n", + " k: Key tensor of shape (..., seq_len_k, d_k)\n", + " v: Value tensor of shape (..., seq_len_k, d_v)\n", + " mask: Optional mask tensor of shape (..., seq_len_q, seq_len_k)\n", + " \n", + " Returns:\n", + " output: Attention output tensor of shape (..., seq_len_q, d_v)\n", + " attention_weights: Attention weights tensor of shape (..., seq_len_q, seq_len_k)\n", + " \"\"\"\n", + " d_k = q.shape[-1] # Get the last dimension size (key dimension)\n", + " \n", + " # Compute the dot product of Q and K^T\n", + " scores = torch.matmul(q, k.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k, dtype=torch.float32))\n", + " \n", + " # Apply mask if provided\n", + " if mask is not None:\n", + " scores = scores.masked_fill(mask == 0, float('-inf'))\n", + " \n", + " # Apply softmax to get attention weights along the last dimension\n", + " attention_weights = F.softmax(scores, dim=-1) # dim=-1 ensures softmax is applied across the last axis\n", + " \n", + " # Compute output by weighting V with the attention weights\n", + " output = torch.matmul(attention_weights, v)\n", + " \n", + " return output, attention_weights" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([1, 3, 3])\n", + "tensor([[[ 6.9352, 6.2411, 8.8509],\n", + " [ 6.1200, 8.0314, 9.2154],\n", + " [ 6.9659, 4.0257, 12.7036]]])\n", + "tensor([[[ 6.9352, 6.2411, 8.8509],\n", + " [ 6.1200, 8.0314, 9.2154],\n", + " [ 6.9659, 4.0257, 12.7036]]])\n" + ] + } + ], + "source": [ + "# Testing on data & compare\n", + "output_custom, _ = scaled_dot_product_attention(q, k, v)\n", + "print(output_custom)\n", + "output = F.scaled_dot_product_attention(q, k, v)\n", + "print(output)\n", + "\n", + "assert torch.allclose(output_custom, output, atol=1e-08, rtol=1e-05) # Check if they are close enough.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/embeddings-q2.ipynb b/llm/embeddings-q2.ipynb new file mode 100644 index 0000000..13581ac --- /dev/null +++ b/llm/embeddings-q2.ipynb @@ -0,0 +1,186 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create embeddings out of an LLM\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "c:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n", + "Generating full split: 701528 examples [00:14, 50103.12 examples/s]\n" + ] + } + ], + "source": [ + "# Load Amazon Reviews dataset\n", + "from datasets import load_dataset\n", + "dataset = load_dataset(\"McAuley-Lab/Amazon-Reviews-2023\", \"raw_review_All_Beauty\", trust_remote_code=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True\n" + ] + }, + { + "data": { + "text/plain": [ + "LlamaForCausalLM(\n", + " (model): LlamaModel(\n", + " (embed_tokens): Embedding(49152, 576)\n", + " (layers): ModuleList(\n", + " (0-29): 30 x LlamaDecoderLayer(\n", + " (self_attn): LlamaAttention(\n", + " (q_proj): Linear(in_features=576, out_features=576, bias=False)\n", + " (k_proj): Linear(in_features=576, out_features=192, bias=False)\n", + " (v_proj): Linear(in_features=576, out_features=192, bias=False)\n", + " (o_proj): Linear(in_features=576, out_features=576, bias=False)\n", + " )\n", + " (mlp): LlamaMLP(\n", + " (gate_proj): Linear(in_features=576, out_features=1536, bias=False)\n", + " (up_proj): Linear(in_features=576, out_features=1536, bias=False)\n", + " (down_proj): Linear(in_features=1536, out_features=576, bias=False)\n", + " (act_fn): SiLU()\n", + " )\n", + " (input_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", + " (post_attention_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", + " )\n", + " )\n", + " (norm): LlamaRMSNorm((576,), eps=1e-05)\n", + " (rotary_emb): LlamaRotaryEmbedding()\n", + " )\n", + " (lm_head): Linear(in_features=576, out_features=49152, bias=False)\n", + ")" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# Load SmolLM2-135M model and tokenizer\n", + "from transformers import AutoTokenizer, AutoModelForCausalLM\n", + "\n", + "# Load model and tokenizer\n", + "tokenizer = AutoTokenizer.from_pretrained(\"HuggingFaceTB/SmolLM2-135M\")\n", + "model = AutoModelForCausalLM.from_pretrained(\"HuggingFaceTB/SmolLM2-135M\")\n", + "print(isinstance(model, torch.nn.Module)) # Should print: True\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "model.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LlamaForCausalLM(\n", + " (model): LlamaModel(\n", + " (embed_tokens): Embedding(49152, 576)\n", + " (layers): ModuleList(\n", + " (0-29): 30 x LlamaDecoderLayer(\n", + " (self_attn): LlamaAttention(\n", + " (q_proj): Linear(in_features=576, out_features=576, bias=False)\n", + " (k_proj): Linear(in_features=576, out_features=192, bias=False)\n", + " (v_proj): Linear(in_features=576, out_features=192, bias=False)\n", + " (o_proj): Linear(in_features=576, out_features=576, bias=False)\n", + " )\n", + " (mlp): LlamaMLP(\n", + " (gate_proj): Linear(in_features=576, out_features=1536, bias=False)\n", + " (up_proj): Linear(in_features=576, out_features=1536, bias=False)\n", + " (down_proj): Linear(in_features=1536, out_features=576, bias=False)\n", + " (act_fn): SiLU()\n", + " )\n", + " (input_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", + " (post_attention_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", + " )\n", + " )\n", + " (norm): LlamaRMSNorm((576,), eps=1e-05)\n", + " (rotary_emb): LlamaRotaryEmbedding()\n", + " )\n", + " (lm_head): Linear(in_features=576, out_features=49152, bias=False)\n", + ")" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/template.ipynb b/template.ipynb deleted file mode 100644 index e6a7675..0000000 --- a/template.ipynb +++ /dev/null @@ -1,100 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Header\n", - "\n", - "
\n", - " ๐Ÿ’ก Hint\n", - " Some details: https://pytorch.org/tutorials/beginner/examples_autograd/two_layer_net_custom_function.html\n", - "
\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Generate synthetic data\n", - "torch.manual_seed(42)\n", - "X = torch.rand(100, 1) * 10 # 100 data points between 0 and 10\n", - "y = 2 * X + 3 + torch.randn(100, 1) # Linear relationship with noise" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Define the Linear Regression Model\n", - "class LinearRegressionModel(nn.Module):\n", - " def __init__(self):\n", - " super(LinearRegressionModel, self).__init__()\n", - " self.linear = nn.Linear(1, 1) # Single input and single output\n", - "\n", - " def forward(self, x):\n", - " return self.linear(x)\n", - "\n", - "# Initialize the model, loss function, and optimizer\n", - "model = LinearRegressionModel()\n", - "criterion = nn.MSELoss()\n", - "optimizer = optim.SGD(model.parameters(), lr=0.01)\n", - "\n", - "# Training loop\n", - "epochs = 1000\n", - "for epoch in range(epochs):\n", - " # Forward pass\n", - " predictions = model(X)\n", - " loss = criterion(predictions, y)\n", - "\n", - " # Backward pass and optimization\n", - " optimizer.zero_grad()\n", - " loss.backward()\n", - " optimizer.step()\n", - "\n", - " # Log progress every 100 epochs\n", - " if (epoch + 1) % 100 == 0:\n", - " print(f\"Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Display the learned parameters\n", - "[w, b] = model.linear.parameters()\n", - "print(f\"Learned weight: {w.item():.4f}, Learned bias: {b.item():.4f}\")\n", - "\n", - "# Testing on new data\n", - "X_test = torch.tensor([[4.0], [7.0]])\n", - "with torch.no_grad():\n", - " predictions = model(X_test)\n", - " print(f\"Predictions for {X_test.tolist()}: {predictions.tolist()}\")" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/e1/lin-regression.ipynb b/torch/easy/e1/lin-regression.ipynb similarity index 100% rename from e1/lin-regression.ipynb rename to torch/easy/e1/lin-regression.ipynb diff --git a/e1/lin-regression_SOLN.ipynb b/torch/easy/e1/lin-regression_SOLN.ipynb similarity index 100% rename from e1/lin-regression_SOLN.ipynb rename to torch/easy/e1/lin-regression_SOLN.ipynb diff --git a/e2/custom-dataset.ipynb b/torch/easy/e2/custom-dataset.ipynb similarity index 100% rename from e2/custom-dataset.ipynb rename to torch/easy/e2/custom-dataset.ipynb diff --git a/e2/custom-dataset_SOLN.ipynb b/torch/easy/e2/custom-dataset_SOLN.ipynb similarity index 100% rename from e2/custom-dataset_SOLN.ipynb rename to torch/easy/e2/custom-dataset_SOLN.ipynb diff --git a/e2/data.csv b/torch/easy/e2/data.csv similarity index 100% rename from e2/data.csv rename to torch/easy/e2/data.csv diff --git a/e3/custom-activation.ipynb b/torch/easy/e3/custom-activation.ipynb similarity index 100% rename from e3/custom-activation.ipynb rename to torch/easy/e3/custom-activation.ipynb diff --git a/e3/custom-activation_SOLN.ipynb b/torch/easy/e3/custom-activation_SOLN.ipynb similarity index 100% rename from e3/custom-activation_SOLN.ipynb rename to torch/easy/e3/custom-activation_SOLN.ipynb diff --git a/e4/custom-loss.ipynb b/torch/easy/e4/custom-loss.ipynb similarity index 100% rename from e4/custom-loss.ipynb rename to torch/easy/e4/custom-loss.ipynb diff --git a/e4/custom-loss_SOLN.ipynb b/torch/easy/e4/custom-loss_SOLN.ipynb similarity index 100% rename from e4/custom-loss_SOLN.ipynb rename to torch/easy/e4/custom-loss_SOLN.ipynb diff --git a/e5/custon-DNN.ipynb b/torch/easy/e5/custon-DNN.ipynb similarity index 100% rename from e5/custon-DNN.ipynb rename to torch/easy/e5/custon-DNN.ipynb diff --git a/e5/custon-DNN_SOLN.ipynb b/torch/easy/e5/custon-DNN_SOLN.ipynb similarity index 100% rename from e5/custon-DNN_SOLN.ipynb rename to torch/easy/e5/custon-DNN_SOLN.ipynb diff --git a/e6/tensorboard.ipynb b/torch/easy/e6/tensorboard.ipynb similarity index 100% rename from e6/tensorboard.ipynb rename to torch/easy/e6/tensorboard.ipynb diff --git a/e6/tensorboard_SOLN.ipynb b/torch/easy/e6/tensorboard_SOLN.ipynb similarity index 100% rename from e6/tensorboard_SOLN.ipynb rename to torch/easy/e6/tensorboard_SOLN.ipynb diff --git a/e7/save_model.ipynb b/torch/easy/e7/save_model.ipynb similarity index 100% rename from e7/save_model.ipynb rename to torch/easy/e7/save_model.ipynb diff --git a/e7/save_model_SOLN.ipynb b/torch/easy/e7/save_model_SOLN.ipynb similarity index 100% rename from e7/save_model_SOLN.ipynb rename to torch/easy/e7/save_model_SOLN.ipynb diff --git a/h1/custom-autgrad-function.ipynb b/torch/hard/h1/custom-autgrad-function.ipynb similarity index 100% rename from h1/custom-autgrad-function.ipynb rename to torch/hard/h1/custom-autgrad-function.ipynb diff --git a/h1/custom-autgrad-function_SOLN.ipynb b/torch/hard/h1/custom-autgrad-function_SOLN.ipynb similarity index 100% rename from h1/custom-autgrad-function_SOLN.ipynb rename to torch/hard/h1/custom-autgrad-function_SOLN.ipynb diff --git a/h10/xai.ipynb b/torch/hard/h10/xai.ipynb similarity index 100% rename from h10/xai.ipynb rename to torch/hard/h10/xai.ipynb diff --git a/h10/xai_SOLN.ipynb b/torch/hard/h10/xai_SOLN.ipynb similarity index 100% rename from h10/xai_SOLN.ipynb rename to torch/hard/h10/xai_SOLN.ipynb diff --git a/h3/transformer.ipynb b/torch/hard/h3/transformer.ipynb similarity index 100% rename from h3/transformer.ipynb rename to torch/hard/h3/transformer.ipynb diff --git a/h3/transformer_SOLN.ipynb b/torch/hard/h3/transformer_SOLN.ipynb similarity index 100% rename from h3/transformer_SOLN.ipynb rename to torch/hard/h3/transformer_SOLN.ipynb diff --git a/h4/GAN.ipynb b/torch/hard/h4/GAN.ipynb similarity index 100% rename from h4/GAN.ipynb rename to torch/hard/h4/GAN.ipynb diff --git a/h4/GAN_SOLN.ipynb b/torch/hard/h4/GAN_SOLN.ipynb similarity index 100% rename from h4/GAN_SOLN.ipynb rename to torch/hard/h4/GAN_SOLN.ipynb diff --git a/h5/seq-to-seq-with-Attention.ipynb b/torch/hard/h5/seq-to-seq-with-Attention.ipynb similarity index 100% rename from h5/seq-to-seq-with-Attention.ipynb rename to torch/hard/h5/seq-to-seq-with-Attention.ipynb diff --git a/h5/seq-to-seq-with-Attention_SOLN.ipynb b/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb similarity index 100% rename from h5/seq-to-seq-with-Attention_SOLN.ipynb rename to torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb diff --git a/h6/quantize-language-model.ipynb b/torch/hard/h6/quantize-language-model.ipynb similarity index 100% rename from h6/quantize-language-model.ipynb rename to torch/hard/h6/quantize-language-model.ipynb diff --git a/h6/quantize-language-model_SOLN.ipynb b/torch/hard/h6/quantize-language-model_SOLN.ipynb similarity index 100% rename from h6/quantize-language-model_SOLN.ipynb rename to torch/hard/h6/quantize-language-model_SOLN.ipynb diff --git a/h9/cuda-amp.ipynb b/torch/hard/h9/cuda-amp.ipynb similarity index 100% rename from h9/cuda-amp.ipynb rename to torch/hard/h9/cuda-amp.ipynb diff --git a/h9/cuda-amp_SOLN.ipynb b/torch/hard/h9/cuda-amp_SOLN.ipynb similarity index 100% rename from h9/cuda-amp_SOLN.ipynb rename to torch/hard/h9/cuda-amp_SOLN.ipynb diff --git a/m1/LSTM.ipynb b/torch/medium/m1/LSTM.ipynb similarity index 100% rename from m1/LSTM.ipynb rename to torch/medium/m1/LSTM.ipynb diff --git a/m1/LSTM_SOLN.ipynb b/torch/medium/m1/LSTM_SOLN.ipynb similarity index 100% rename from m1/LSTM_SOLN.ipynb rename to torch/medium/m1/LSTM_SOLN.ipynb diff --git a/m2/CNN.ipynb b/torch/medium/m2/CNN.ipynb similarity index 100% rename from m2/CNN.ipynb rename to torch/medium/m2/CNN.ipynb diff --git a/m2/CNN_SOLN.ipynb b/torch/medium/m2/CNN_SOLN.ipynb similarity index 100% rename from m2/CNN_SOLN.ipynb rename to torch/medium/m2/CNN_SOLN.ipynb diff --git a/m3/CNN_ParamInit.ipynb b/torch/medium/m3/CNN_ParamInit.ipynb similarity index 100% rename from m3/CNN_ParamInit.ipynb rename to torch/medium/m3/CNN_ParamInit.ipynb diff --git a/m3/CNN_ParamInit_SOLN.ipynb b/torch/medium/m3/CNN_ParamInit_SOLN.ipynb similarity index 100% rename from m3/CNN_ParamInit_SOLN.ipynb rename to torch/medium/m3/CNN_ParamInit_SOLN.ipynb diff --git a/m4/RNN.ipynb b/torch/medium/m4/RNN.ipynb similarity index 100% rename from m4/RNN.ipynb rename to torch/medium/m4/RNN.ipynb diff --git a/m4/RNN_SOLN.ipynb b/torch/medium/m4/RNN_SOLN.ipynb similarity index 100% rename from m4/RNN_SOLN.ipynb rename to torch/medium/m4/RNN_SOLN.ipynb diff --git a/m5/augmentation.ipynb b/torch/medium/m5/augmentation.ipynb similarity index 100% rename from m5/augmentation.ipynb rename to torch/medium/m5/augmentation.ipynb diff --git a/m5/augmentation_SOLN.ipynb b/torch/medium/m5/augmentation_SOLN.ipynb similarity index 100% rename from m5/augmentation_SOLN.ipynb rename to torch/medium/m5/augmentation_SOLN.ipynb diff --git a/m6/bench.ipynb b/torch/medium/m6/bench.ipynb similarity index 100% rename from m6/bench.ipynb rename to torch/medium/m6/bench.ipynb diff --git a/m6/bench_SOLN.ipynb b/torch/medium/m6/bench_SOLN.ipynb similarity index 100% rename from m6/bench_SOLN.ipynb rename to torch/medium/m6/bench_SOLN.ipynb diff --git a/m7/autoencoder.ipynb b/torch/medium/m7/autoencoder.ipynb similarity index 100% rename from m7/autoencoder.ipynb rename to torch/medium/m7/autoencoder.ipynb diff --git a/m7/autoencoder_SOLN.ipynb b/torch/medium/m7/autoencoder_SOLN.ipynb similarity index 100% rename from m7/autoencoder_SOLN.ipynb rename to torch/medium/m7/autoencoder_SOLN.ipynb From 5b1d80ab9c90ed28656b6828f5380985fdc88e10 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 17 Feb 2025 13:45:07 -0500 Subject: [PATCH 02/40] Init Multi-Head-Attention --- README.md | 29 ++-- llm/multi-head-attention-q5.ipynb | 237 ++++++++++++++++++++++++++++++ 2 files changed, 252 insertions(+), 14 deletions(-) create mode 100644 llm/multi-head-attention-q5.ipynb diff --git a/README.md b/README.md index 94cddf0..1a4d8e2 100644 --- a/README.md +++ b/README.md @@ -74,20 +74,21 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 2. Create an embeddings out of an LLM 3. Implement Predictive Prefill with Speculative Decoding 4. Implement Attention from Scratch -5. Implement KV Cache in Multi-Head Attention from Scratch -6. Implement Sinusoidal Embeddings -7. Implement ROPE Embeddings -8. Implement SmolLM from Scratch -9. Implement Beam Search atop LLM for decoding -10. Implement Top K Sampling atop LLM for decoding -11. Implement Top p Sampling atop LLM for decoding -12. Implement Temperature Sampling atop LLM for decoding -13. Implement LoRA on a layer of an LLM -14. Mix two models to create a mixture of Experts -15. Apply SFT on SmolLM -16. Apply RLHF on SmolLM -17. Implement DPO based RLHF -18. Add continous batching to your LLM +5. Implement Multi-Head Attention from Scratch +6. Implement KV Cache in Multi-Head Attention from Scratch +7. Implement Sinusoidal Embeddings +8. Implement ROPE Embeddings +9. Implement SmolLM from Scratch +10. Implement Beam Search atop LLM for decoding +11. Implement Top K Sampling atop LLM for decoding +12. Implement Top p Sampling atop LLM for decoding +13. Implement Temperature Sampling atop LLM for decoding +14. Implement LoRA on a layer of an LLM +15. Mix two models to create a mixture of Experts +16. Apply SFT on SmolLM +17. Apply RLHF on SmolLM +18. Implement DPO based RLHF +19. Add continous batching to your LLM **What's cool? ๐Ÿš€** - **Diverse Questions**: Covers beginner to advanced PyTorch concepts (e.g., tensors, autograd, CNNs, GANs, and more). diff --git a/llm/multi-head-attention-q5.ipynb b/llm/multi-head-attention-q5.ipynb new file mode 100644 index 0000000..4d01130 --- /dev/null +++ b/llm/multi-head-attention-q5.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([3, 4, 8])\n" + ] + } + ], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "\n", + "\n", + "\n", + "def multi_head_attention(q, k, v, num_heads, d_model, mask=None):\n", + " \"\"\"\n", + " Implements multi-head attention.\n", + " \n", + " Args:\n", + " q (Tensor): Query tensor of shape (batch_size, seq_len, d_model)\n", + " k (Tensor): Key tensor of shape (batch_size, seq_len, d_model)\n", + " v (Tensor): Value tensor of shape (batch_size, seq_len, d_model)\n", + " num_heads (int): Number of attention heads\n", + " d_model (int): Total embedding dimension\n", + " mask (Tensor, optional): Masking tensor for attention\n", + " \n", + " Returns:\n", + " Tensor: Multi-head attention output of shape (batch_size, seq_len, d_model)\n", + " \"\"\"\n", + " assert d_model % num_heads == 0\n", + "\n", + " d_head = d_model // num_heads # Head size dimension\n", + " batch_size, seq_len, _ = q.shape\n", + " \n", + " Q_w = nn.Linear(d_model, d_model, bias=False).to(device) # (batch_size, seq_len, d_model)\n", + " K_w = nn.Linear(d_model, d_model, bias=False).to(device)\n", + " V_w = nn.Linear(d_model, d_model, bias=False).to(device)\n", + " W_out = nn.Linear(d_model, d_model, bias=False).to(device)\n", + "\n", + " Q = Q_w(q) # (batch_size, seq_len, d_model)\n", + " K = K_w(k)\n", + " V = V_w(v)\n", + "\n", + " # (batch_size, num_heads, seq_len, d_head)\n", + " Q = Q.view(batch_size, seq_len, num_heads, d_head).transpose(1,2)\n", + " K = K.view(batch_size, seq_len, num_heads, d_head).transpose(1,2)\n", + " V = V.view(batch_size, seq_len, num_heads, d_head).transpose(1,2)\n", + "\n", + " scores = torch.matmul(Q, K.transpose(-2,-1)) / (d_head ** 0.5)\n", + "\n", + " # Mask check\n", + " if mask is not None:\n", + " scores = scores.masked_fill(mask == 0, float('-inf'))\n", + " \n", + " attn_weights = F.softmax(scores, dim=-1)\n", + "\n", + " output = torch.matmul(attn_weights, V) #(batch_size, num_heads, seq_len, d_head)\n", + "\n", + " output = output.transpose(1,2).contiguous().view(batch_size, seq_len, d_model)\n", + " return W_out(output)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([[[-9.5287e-03, -9.4515e-02, 3.6103e-01, 8.3070e-02, -1.4784e-01,\n", + " 1.1758e-01, -2.0393e-02, 7.4377e-02],\n", + " [-1.2889e-02, -9.5831e-02, 3.6233e-01, 8.0714e-02, -1.4981e-01,\n", + " 1.1651e-01, -2.2352e-02, 7.3968e-02],\n", + " [-1.0349e-02, -9.5222e-02, 3.6118e-01, 8.3003e-02, -1.4805e-01,\n", + " 1.1768e-01, -2.0513e-02, 7.4629e-02],\n", + " [-1.3522e-02, -9.6064e-02, 3.6350e-01, 7.9288e-02, -1.5093e-01,\n", + " 1.1577e-01, -2.3686e-02, 7.3739e-02]],\n", + "\n", + " [[ 5.4852e-03, -9.3221e-02, 2.8457e-01, 1.8735e-02, -1.4442e-01,\n", + " 6.7877e-02, -4.0639e-02, 4.1987e-02],\n", + " [ 5.2663e-03, -9.3650e-02, 2.8520e-01, 1.8377e-02, -1.4474e-01,\n", + " 6.8188e-02, -4.1217e-02, 4.1996e-02],\n", + " [ 5.1576e-03, -9.2715e-02, 2.8375e-01, 1.9321e-02, -1.4380e-01,\n", + " 6.7911e-02, -4.0011e-02, 4.1879e-02],\n", + " [ 4.8699e-03, -9.3693e-02, 2.8548e-01, 1.8387e-02, -1.4475e-01,\n", + " 6.8602e-02, -4.1422e-02, 4.1853e-02]],\n", + "\n", + " [[-1.1762e-04, -1.1050e-01, 3.7779e-01, 7.4304e-02, -1.5698e-01,\n", + " 1.1184e-01, -3.4857e-02, 9.1290e-02],\n", + " [ 5.6040e-05, -1.1257e-01, 3.7631e-01, 7.3138e-02, -1.5667e-01,\n", + " 1.1152e-01, -3.5756e-02, 9.2673e-02],\n", + " [-1.7608e-03, -1.1109e-01, 3.7823e-01, 7.4195e-02, -1.5799e-01,\n", + " 1.1120e-01, -3.4515e-02, 9.1650e-02],\n", + " [-1.8293e-03, -1.1139e-01, 3.7759e-01, 7.3821e-02, -1.5798e-01,\n", + " 1.1078e-01, -3.4558e-02, 9.1811e-02]]],\n", + " grad_fn=)\n", + "tensor([[[-0.0920, 0.0041, 0.1783, -0.0985, -0.0072, -0.0573, 0.1370,\n", + " 0.0283],\n", + " [-0.0940, 0.0065, 0.1767, -0.1009, -0.0090, -0.0513, 0.1387,\n", + " 0.0288],\n", + " [-0.0921, 0.0028, 0.1781, -0.0998, -0.0096, -0.0537, 0.1359,\n", + " 0.0288],\n", + " [-0.0904, 0.0028, 0.1794, -0.1025, -0.0108, -0.0520, 0.1356,\n", + " 0.0271]],\n", + "\n", + " [[-0.1378, 0.0525, 0.0711, -0.0071, 0.0343, -0.0524, 0.1119,\n", + " 0.0528],\n", + " [-0.1365, 0.0532, 0.0724, -0.0085, 0.0342, -0.0538, 0.1114,\n", + " 0.0509],\n", + " [-0.1390, 0.0545, 0.0703, -0.0048, 0.0375, -0.0532, 0.1150,\n", + " 0.0536],\n", + " [-0.1376, 0.0545, 0.0708, -0.0063, 0.0379, -0.0539, 0.1129,\n", + " 0.0513]],\n", + "\n", + " [[-0.0968, 0.0384, 0.1665, -0.0740, 0.0471, -0.0413, 0.1904,\n", + " 0.0355],\n", + " [-0.0970, 0.0390, 0.1671, -0.0733, 0.0490, -0.0430, 0.1926,\n", + " 0.0359],\n", + " [-0.0962, 0.0405, 0.1666, -0.0741, 0.0498, -0.0425, 0.1925,\n", + " 0.0345],\n", + " [-0.0945, 0.0414, 0.1651, -0.0762, 0.0501, -0.0393, 0.1909,\n", + " 0.0325]]], grad_fn=)\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[31], line 9\u001b[0m\n\u001b[0;32m 6\u001b[0m output, _ \u001b[38;5;241m=\u001b[39m multihead_attn(q, k, v)\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28mprint\u001b[39m(output)\n\u001b[1;32m----> 9\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mallclose(output_custom, output, atol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1e-08\u001b[39m, rtol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1e-05\u001b[39m) \u001b[38;5;66;03m# Check if they are close enough.\u001b[39;00m\n", + "\u001b[1;31mAssertionError\u001b[0m: " + ] + } + ], + "source": [ + "# Testing on data & compare\n", + "output_custom = multi_head_attention(q, k, v, num_heads, d_model)\n", + "print(output_custom)\n", + "\n", + "multihead_attn = torch.nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, bias=False, batch_first=True)\n", + "output, _ = multihead_attn(q, k, v)\n", + "print(output)\n", + "\n", + "assert torch.allclose(output_custom, output, atol=1e-08, rtol=1e-05) # Check if they are close enough.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 882df6d120258ed0dba571ab68b790963422bac1 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Tue, 18 Feb 2025 10:48:20 -0500 Subject: [PATCH 03/40] Sinusoidal Embeddings --- llm/sinusoidal-q7.ipynb | 169 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 llm/sinusoidal-q7.ipynb diff --git a/llm/sinusoidal-q7.ipynb b/llm/sinusoidal-q7.ipynb new file mode 100644 index 0000000..2895be9 --- /dev/null +++ b/llm/sinusoidal-q7.ipynb @@ -0,0 +1,169 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([3, 4, 8])\n" + ] + } + ], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "class SinusoidalPositionalEmbedding(nn.Module):\n", + " def __init__(self, max_seq_len: int, d_model: int):\n", + " \"\"\"\n", + " Initializes the sinusoidal positional embedding.\n", + " \n", + " Args:\n", + " max_seq_len (int): Maximum sequence length.\n", + " d_model (int): Embedding dimension.\n", + " \"\"\"\n", + " super().__init__()\n", + " \n", + " # Create a matrix of shape (max_seq_len, d_model)\n", + " pe = torch.zeros(max_seq_len, d_model)\n", + " \n", + " # Position indices (0, 1, 2, ..., max_seq_len-1)\n", + " position = torch.arange(0, max_seq_len, dtype=torch.float).unsqueeze(1)\n", + " \n", + " # Compute the div_term using the exponential decay formula\n", + " div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))\n", + " \n", + " # Apply sin to even indices and cos to odd indices\n", + " pe[:, 0::2] = torch.sin(position * div_term)\n", + " pe[:, 1::2] = torch.cos(position * div_term)\n", + " \n", + " # Register as buffer (not a parameter, but saved in the model)\n", + " self.register_buffer(\"pe\", pe)\n", + "\n", + " def forward(self, x):\n", + " \"\"\"\n", + " Returns the positional embedding for a given input tensor.\n", + " \n", + " Args:\n", + " x (Tensor): Input tensor of shape (batch_size, seq_len, d_model).\n", + " \n", + " Returns:\n", + " Tensor: Positional embeddings of shape (batch_size, seq_len, d_model).\n", + " \"\"\"\n", + " return self.pe[:x.shape[1], :].unsqueeze(0) # Shape: (1, seq_len, d_model)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([1, 50, 100])\n" + ] + } + ], + "source": [ + "# from fairseq.modules.sinusoidal_positional_embedding import SinusoidalPositionalEmbedding\n", + "\n", + "max_seq_len = 100\n", + "d_model = 64\n", + "\n", + "# Fairseq's implementation requires the number of embeddings (seq length) and embedding dim\n", + "# pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len, padding_idx=None)\n", + "\n", + "# Generate embeddings for a sequence of length 50\n", + "seq_len = 50\n", + "positions = torch.arange(seq_len).unsqueeze(0) # Shape: (1, seq_len)\n", + "# positional_encoding = pos_emb(positions) # Shape: (1, seq_len, d_model)\n", + "\n", + "custom_pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len)\n", + "\n", + "positional_encoding_custom = custom_pos_emb(positions)\n", + "\n", + "print(positional_encoding_custom.shape) # (1, 50, 64)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f855415bfe889b1f9806da54d82c293dd649299a Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 14 Apr 2025 20:43:29 -0700 Subject: [PATCH 04/40] Update README.md Signed-off-by: Chandrahas Aroori --- README.md | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 1a4d8e2..3f95e81 100644 --- a/README.md +++ b/README.md @@ -68,27 +68,32 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st ## LLM Set -**An all new set of questions to help you understand and implement Large Language Models from scratch. ** - -1. Implement Byte Pair Encoding from Scratch -2. Create an embeddings out of an LLM -3. Implement Predictive Prefill with Speculative Decoding -4. Implement Attention from Scratch -5. Implement Multi-Head Attention from Scratch -6. Implement KV Cache in Multi-Head Attention from Scratch -7. Implement Sinusoidal Embeddings -8. Implement ROPE Embeddings -9. Implement SmolLM from Scratch -10. Implement Beam Search atop LLM for decoding -11. Implement Top K Sampling atop LLM for decoding -12. Implement Top p Sampling atop LLM for decoding -13. Implement Temperature Sampling atop LLM for decoding -14. Implement LoRA on a layer of an LLM -15. Mix two models to create a mixture of Experts -16. Apply SFT on SmolLM -17. Apply RLHF on SmolLM -18. Implement DPO based RLHF -19. Add continous batching to your LLM +**An all new set of questions to help you understand and implement Large Language Models from scratch.** + +1. Implement KL Divergence Loss +2. Implement Byte Pair Encoding from Scratch +3. Create an embeddings out of an LLM +4. Implement Predictive Prefill with Speculative Decoding +5. Implement Attention from Scratch +6. Implement Multi-Head Attention from Scratch +7. Implement KV Cache in Multi-Head Attention from Scratch +8. Implement Sinusoidal Embeddings +9. Implement ROPE Embeddings +10. Implement SmolLM from Scratch +11. Implement Quantization of Models + a. Types of Quantization +12. Implement Beam Search atop LLM for decoding +13. Implement Top K Sampling atop LLM for decoding +14. Implement Top p Sampling atop LLM for decoding +15. Implement Temperature Sampling atop LLM for decoding +16. Implement LoRA on a layer of an LLM +17. Mix two models to create a mixture of Experts +18. Apply SFT on SmolLM +19. Apply RLHF on SmolLM +20. Implement DPO based RLHF +21. Add continous batching to your LLM +22. Chunk Textual Data for Dense Passage Retreival +23. Implement Lage scale Training => 5D Parallelism **What's cool? ๐Ÿš€** - **Diverse Questions**: Covers beginner to advanced PyTorch concepts (e.g., tensors, autograd, CNNs, GANs, and more). From 6712c9a44c1cca732a4b4c73765ca9c3817f7997 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Wed, 7 May 2025 17:22:30 -0700 Subject: [PATCH 05/40] Rope --- Tricks.md | 9 ++ llm/rope-q8.ipynb | 164 +++++++++++++++++++++++++++++ torch/easy/e1/lin-regression.ipynb | 20 +--- 3 files changed, 177 insertions(+), 16 deletions(-) create mode 100644 Tricks.md create mode 100644 llm/rope-q8.ipynb diff --git a/Tricks.md b/Tricks.md new file mode 100644 index 0000000..bc1fab6 --- /dev/null +++ b/Tricks.md @@ -0,0 +1,9 @@ +# Tricks + +List of tricks in pytorch + + +## TorchScript +@torch.jit.scriptorch.jit.script + +## Unit Tests in PyTorch \ No newline at end of file diff --git a/llm/rope-q8.ipynb b/llm/rope-q8.ipynb new file mode 100644 index 0000000..0cd7b52 --- /dev/null +++ b/llm/rope-q8.ipynb @@ -0,0 +1,164 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement ROPE from Scratch\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([3, 4, 8])\n" + ] + } + ], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Rotary(torch.nn.Module):\n", + " def __init__(self, dim, base=10000):\n", + " super().__init__()\n", + " inv_freq = 1.0 / (base ** (torch.arange(0, dim, 2).float() / dim))\n", + " self.register_buffer(\"inv_freq\", inv_freq)\n", + " self.seq_len_cached = None\n", + " self.cos_cached = None\n", + " self.sin_cached = None\n", + "\n", + " def forward(self, x, seq_dim=1):\n", + " seq_len = x.shape[seq_dim]\n", + " if seq_len != self.seq_len_cached:\n", + " self.seq_len_cached = seq_len\n", + " t = torch.arange(x.shape[seq_dim], device=x.device).type_as(self.inv_freq)\n", + " freqs = torch.einsum(\"i,j->ij\", t, self.inv_freq)\n", + " emb = torch.cat((freqs, freqs), dim=-1).to(x.device)\n", + " self.cos_cached = emb.cos()[:, None, None, :]\n", + " self.sin_cached = emb.sin()[:, None, None, :]\n", + " return self.cos_cached, self.sin_cached\n", + "\n", + "\n", + "# rotary pos emb helpers:\n", + "\n", + "def rotate_half(x):\n", + " x1, x2 = x[..., : x.shape[-1] // 2], x[..., x.shape[-1] // 2 :]\n", + " return torch.cat(\n", + " (-x2, x1), dim=x1.ndim - 1\n", + " ) # dim=-1 triggers a bug in torch < 1.8.0\n", + "\n", + "\n", + "@torch.jit.script\n", + "def apply_rotary_pos_emb(q, k, cos, sin):\n", + " return (q * cos) + (rotate_half(q) * sin), (k * cos) + (rotate_half(k) * sin)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([1, 50, 100])\n" + ] + } + ], + "source": [ + "# from fairseq.modules.sinusoidal_positional_embedding import SinusoidalPositionalEmbedding\n", + "\n", + "max_seq_len = 100\n", + "d_model = 64\n", + "\n", + "# Fairseq's implementation requires the number of embeddings (seq length) and embedding dim\n", + "# pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len, padding_idx=None)\n", + "\n", + "# Generate embeddings for a sequence of length 50\n", + "seq_len = 50\n", + "positions = torch.arange(seq_len).unsqueeze(0) # Shape: (1, seq_len)\n", + "# positional_encoding = pos_emb(positions) # Shape: (1, seq_len, d_model)\n", + "\n", + "custom_pos_emb = Rotary(d_model, max_seq_len)\n", + "\n", + "positional_encoding_custom = apply_rotary_pos_emb(positions)\n", + "\n", + "print(positional_encoding_custom.shape) # (1, 50, 64)\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/torch/easy/e1/lin-regression.ipynb b/torch/easy/e1/lin-regression.ipynb index b16371a..546fb03 100644 --- a/torch/easy/e1/lin-regression.ipynb +++ b/torch/easy/e1/lin-regression.ipynb @@ -20,11 +20,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "vscode": { - "languageId": "plaintext" - } - }, + "metadata": {}, "outputs": [], "source": [ "import torch\n", @@ -35,11 +31,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "vscode": { - "languageId": "plaintext" - } - }, + "metadata": {}, "outputs": [], "source": [ "# Generate synthetic data\n", @@ -51,7 +43,7 @@ "#TODO: Add the layer and forward implementation\n", "class LinearRegressionModel(nn.Module):\n", " def __init__(self):\n", - " ...\n", + " layer = torch.nn.layer()\n", "\n", " def forward(self, x):\n", " ...\n", @@ -81,11 +73,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "vscode": { - "languageId": "plaintext" - } - }, + "metadata": {}, "outputs": [], "source": [ "# Display the learned parameters\n", From 3afa6ec80dab89e6c42fac7a97ae233b88bee3bd Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 18 May 2025 07:10:33 -0700 Subject: [PATCH 06/40] Changes --- README.md | 35 ++--- llm/grouped-query-attention.ipynb | 244 ++++++++++++++++++++++++++++++ 2 files changed, 262 insertions(+), 17 deletions(-) create mode 100644 llm/grouped-query-attention.ipynb diff --git a/README.md b/README.md index 3f95e81..6696045 100644 --- a/README.md +++ b/README.md @@ -76,24 +76,25 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 4. Implement Predictive Prefill with Speculative Decoding 5. Implement Attention from Scratch 6. Implement Multi-Head Attention from Scratch -7. Implement KV Cache in Multi-Head Attention from Scratch -8. Implement Sinusoidal Embeddings -9. Implement ROPE Embeddings -10. Implement SmolLM from Scratch -11. Implement Quantization of Models +7. Implement Grouped Query Attention from Scratch +8. Implement KV Cache in Multi-Head Attention from Scratch +9. Implement Sinusoidal Embeddings +10. Implement ROPE Embeddings +11. Implement SmolLM from Scratch +12. Implement Quantization of Models a. Types of Quantization -12. Implement Beam Search atop LLM for decoding -13. Implement Top K Sampling atop LLM for decoding -14. Implement Top p Sampling atop LLM for decoding -15. Implement Temperature Sampling atop LLM for decoding -16. Implement LoRA on a layer of an LLM -17. Mix two models to create a mixture of Experts -18. Apply SFT on SmolLM -19. Apply RLHF on SmolLM -20. Implement DPO based RLHF -21. Add continous batching to your LLM -22. Chunk Textual Data for Dense Passage Retreival -23. Implement Lage scale Training => 5D Parallelism +13. Implement Beam Search atop LLM for decoding +14. Implement Top K Sampling atop LLM for decoding +15. Implement Top p Sampling atop LLM for decoding +16. Implement Temperature Sampling atop LLM for decoding +17. Implement LoRA on a layer of an LLM +18. Mix two models to create a mixture of Experts +19. Apply SFT on SmolLM +20. Apply RLHF on SmolLM +21. Implement DPO based RLHF +22. Add continous batching to your LLM +23. Chunk Textual Data for Dense Passage Retreival +24. Implement Lage scale Training => 5D Parallelism **What's cool? ๐Ÿš€** - **Diverse Questions**: Covers beginner to advanced PyTorch concepts (e.g., tensors, autograd, CNNs, GANs, and more). diff --git a/llm/grouped-query-attention.ipynb b/llm/grouped-query-attention.ipynb new file mode 100644 index 0000000..ed2bb30 --- /dev/null +++ b/llm/grouped-query-attention.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "\n", + "\n", + "### Requirements\n", + "1. \n", + "\n", + "### Constraints\n", + "- \n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Some details: \n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([3, 4, 8])\n" + ] + } + ], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "def grouped_query_attention(q, k, v, num_query_groups, d_model, mask=None):\n", + " \"\"\"\n", + " Implements Grouped Query Attention (GQA).\n", + "\n", + " Args:\n", + " q (Tensor): Query tensor of shape (batch_size, seq_len, d_model)\n", + " k (Tensor): Key tensor of shape (batch_size, seq_len, d_model)\n", + " v (Tensor): Value tensor of shape (batch_size, seq_len, d_model)\n", + " num_query_groups (int): Number of key/value groups (fewer than query groups)\n", + " d_model (int): Total embedding dimension\n", + " mask (Tensor, optional): Masking tensor for attention\n", + "\n", + " Returns:\n", + " Tensor: GQA output of shape (batch_size, seq_len, d_model)\n", + " \"\"\"\n", + " num_query_heads = d_model // 64 # Usually set like in MHA (e.g., 8 heads if d_model=512)\n", + " assert d_model % num_query_heads == 0\n", + " assert num_query_heads % num_query_groups == 0\n", + "\n", + " d_head = d_model // num_query_heads\n", + " batch_size, seq_len, _ = q.shape\n", + "\n", + " Q_w = nn.Linear(d_model, d_model, bias=False).to(q.device)\n", + " K_w = nn.Linear(d_model, d_model * num_query_groups // num_query_heads, bias=False).to(q.device)\n", + " V_w = nn.Linear(d_model, d_model * num_query_groups // num_query_heads, bias=False).to(q.device)\n", + " W_out = nn.Linear(d_model, d_model, bias=False).to(q.device)\n", + "\n", + " Q = Q_w(q) # (batch_size, seq_len, d_model)\n", + " K = K_w(k) # (batch_size, seq_len, d_model * r), r = num_query_groups / num_query_heads\n", + " V = V_w(v)\n", + "\n", + " Q = Q.view(batch_size, seq_len, num_query_heads, d_head).transpose(1, 2) # (batch, heads, seq, d_head)\n", + "\n", + " # Expand keys/values per group\n", + " d_kv = d_model // num_query_groups\n", + " K = K.view(batch_size, seq_len, num_query_groups, d_kv).transpose(1, 2) # (batch, kv_groups, seq, d_kv)\n", + " V = V.view(batch_size, seq_len, num_query_groups, d_kv).transpose(1, 2)\n", + "\n", + " # Repeat K/V for matching Q heads\n", + " repeat_factor = num_query_heads // num_query_groups\n", + " K = K.repeat_interleave(repeat_factor, dim=1) # (batch, heads, seq, d_kv)\n", + " V = V.repeat_interleave(repeat_factor, dim=1)\n", + "\n", + " scores = torch.matmul(Q, K.transpose(-2, -1)) / (d_head ** 0.5) # (batch, heads, seq, seq)\n", + "\n", + " if mask is not None:\n", + " scores = scores.masked_fill(mask == 0, float('-inf'))\n", + "\n", + " attn_weights = F.softmax(scores, dim=-1)\n", + " output = torch.matmul(attn_weights, V) # (batch, heads, seq, d_head)\n", + "\n", + " output = output.transpose(1, 2).contiguous().view(batch_size, seq_len, d_model)\n", + " return W_out(output)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "tensor([[[-9.5287e-03, -9.4515e-02, 3.6103e-01, 8.3070e-02, -1.4784e-01,\n", + " 1.1758e-01, -2.0393e-02, 7.4377e-02],\n", + " [-1.2889e-02, -9.5831e-02, 3.6233e-01, 8.0714e-02, -1.4981e-01,\n", + " 1.1651e-01, -2.2352e-02, 7.3968e-02],\n", + " [-1.0349e-02, -9.5222e-02, 3.6118e-01, 8.3003e-02, -1.4805e-01,\n", + " 1.1768e-01, -2.0513e-02, 7.4629e-02],\n", + " [-1.3522e-02, -9.6064e-02, 3.6350e-01, 7.9288e-02, -1.5093e-01,\n", + " 1.1577e-01, -2.3686e-02, 7.3739e-02]],\n", + "\n", + " [[ 5.4852e-03, -9.3221e-02, 2.8457e-01, 1.8735e-02, -1.4442e-01,\n", + " 6.7877e-02, -4.0639e-02, 4.1987e-02],\n", + " [ 5.2663e-03, -9.3650e-02, 2.8520e-01, 1.8377e-02, -1.4474e-01,\n", + " 6.8188e-02, -4.1217e-02, 4.1996e-02],\n", + " [ 5.1576e-03, -9.2715e-02, 2.8375e-01, 1.9321e-02, -1.4380e-01,\n", + " 6.7911e-02, -4.0011e-02, 4.1879e-02],\n", + " [ 4.8699e-03, -9.3693e-02, 2.8548e-01, 1.8387e-02, -1.4475e-01,\n", + " 6.8602e-02, -4.1422e-02, 4.1853e-02]],\n", + "\n", + " [[-1.1762e-04, -1.1050e-01, 3.7779e-01, 7.4304e-02, -1.5698e-01,\n", + " 1.1184e-01, -3.4857e-02, 9.1290e-02],\n", + " [ 5.6040e-05, -1.1257e-01, 3.7631e-01, 7.3138e-02, -1.5667e-01,\n", + " 1.1152e-01, -3.5756e-02, 9.2673e-02],\n", + " [-1.7608e-03, -1.1109e-01, 3.7823e-01, 7.4195e-02, -1.5799e-01,\n", + " 1.1120e-01, -3.4515e-02, 9.1650e-02],\n", + " [-1.8293e-03, -1.1139e-01, 3.7759e-01, 7.3821e-02, -1.5798e-01,\n", + " 1.1078e-01, -3.4558e-02, 9.1811e-02]]],\n", + " grad_fn=)\n", + "tensor([[[-0.0920, 0.0041, 0.1783, -0.0985, -0.0072, -0.0573, 0.1370,\n", + " 0.0283],\n", + " [-0.0940, 0.0065, 0.1767, -0.1009, -0.0090, -0.0513, 0.1387,\n", + " 0.0288],\n", + " [-0.0921, 0.0028, 0.1781, -0.0998, -0.0096, -0.0537, 0.1359,\n", + " 0.0288],\n", + " [-0.0904, 0.0028, 0.1794, -0.1025, -0.0108, -0.0520, 0.1356,\n", + " 0.0271]],\n", + "\n", + " [[-0.1378, 0.0525, 0.0711, -0.0071, 0.0343, -0.0524, 0.1119,\n", + " 0.0528],\n", + " [-0.1365, 0.0532, 0.0724, -0.0085, 0.0342, -0.0538, 0.1114,\n", + " 0.0509],\n", + " [-0.1390, 0.0545, 0.0703, -0.0048, 0.0375, -0.0532, 0.1150,\n", + " 0.0536],\n", + " [-0.1376, 0.0545, 0.0708, -0.0063, 0.0379, -0.0539, 0.1129,\n", + " 0.0513]],\n", + "\n", + " [[-0.0968, 0.0384, 0.1665, -0.0740, 0.0471, -0.0413, 0.1904,\n", + " 0.0355],\n", + " [-0.0970, 0.0390, 0.1671, -0.0733, 0.0490, -0.0430, 0.1926,\n", + " 0.0359],\n", + " [-0.0962, 0.0405, 0.1666, -0.0741, 0.0498, -0.0425, 0.1925,\n", + " 0.0345],\n", + " [-0.0945, 0.0414, 0.1651, -0.0762, 0.0501, -0.0393, 0.1909,\n", + " 0.0325]]], grad_fn=)\n" + ] + }, + { + "ename": "AssertionError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[31], line 9\u001b[0m\n\u001b[0;32m 6\u001b[0m output, _ \u001b[38;5;241m=\u001b[39m multihead_attn(q, k, v)\n\u001b[0;32m 7\u001b[0m \u001b[38;5;28mprint\u001b[39m(output)\n\u001b[1;32m----> 9\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mallclose(output_custom, output, atol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1e-08\u001b[39m, rtol\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m1e-05\u001b[39m) \u001b[38;5;66;03m# Check if they are close enough.\u001b[39;00m\n", + "\u001b[1;31mAssertionError\u001b[0m: " + ] + } + ], + "source": [ + "# Temporarily set\n", + "num_query_heads = 8\n", + "num_query_groups = 8 # => GQA behaves like MHA\n", + "\n", + "# Use same d_model and input\n", + "multihead_attn = torch.nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, bias=False, batch_first=True)\n", + "output_ref, _ = multihead_attn(q, k, v)\n", + "output_custom = grouped_query_attention(q, k, v, num_query_groups=num_query_groups, d_model=d_model)\n", + "\n", + "# Compare\n", + "assert torch.allclose(output_custom, output_ref, atol=1e-8, rtol=1e-5)\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From d854e1e9aba5c0c968813893cdeaf34cfdbdf15c Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 18 May 2025 08:55:50 -0700 Subject: [PATCH 07/40] BPE --- README.md | 49 ++++++++-------- llm/BPE-q3.ipynb | 147 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 25 deletions(-) create mode 100644 llm/BPE-q3.ipynb diff --git a/README.md b/README.md index 6696045..e7abc18 100644 --- a/README.md +++ b/README.md @@ -39,8 +39,6 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 5. [Implement a Deep Neural Network](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN_SOLN.ipynb) 6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard_SOLN.ipynb) 7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model_SOLN.ipynb) -8. Implement RMS Norm -9. Implement KL divergence loss 10. Implement Softmax function from scratch @@ -71,30 +69,31 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st **An all new set of questions to help you understand and implement Large Language Models from scratch.** 1. Implement KL Divergence Loss -2. Implement Byte Pair Encoding from Scratch -3. Create an embeddings out of an LLM -4. Implement Predictive Prefill with Speculative Decoding -5. Implement Attention from Scratch -6. Implement Multi-Head Attention from Scratch -7. Implement Grouped Query Attention from Scratch -8. Implement KV Cache in Multi-Head Attention from Scratch -9. Implement Sinusoidal Embeddings -10. Implement ROPE Embeddings -11. Implement SmolLM from Scratch -12. Implement Quantization of Models +2. Implement RMS Norm +3. Implement Byte Pair Encoding from Scratch +4. Create an embeddings out of an LLM +5. Implement Predictive Prefill with Speculative Decoding +6. Implement Attention from Scratch +7. Implement Multi-Head Attention from Scratch +8. Implement Grouped Query Attention from Scratch +9. Implement KV Cache in Multi-Head Attention from Scratch +10. Implement Sinusoidal Embeddings +11. Implement ROPE Embeddings +12. Implement SmolLM from Scratch +13. Implement Quantization of Models a. Types of Quantization -13. Implement Beam Search atop LLM for decoding -14. Implement Top K Sampling atop LLM for decoding -15. Implement Top p Sampling atop LLM for decoding -16. Implement Temperature Sampling atop LLM for decoding -17. Implement LoRA on a layer of an LLM -18. Mix two models to create a mixture of Experts -19. Apply SFT on SmolLM -20. Apply RLHF on SmolLM -21. Implement DPO based RLHF -22. Add continous batching to your LLM -23. Chunk Textual Data for Dense Passage Retreival -24. Implement Lage scale Training => 5D Parallelism +14. Implement Beam Search atop LLM for decoding +15. Implement Top K Sampling atop LLM for decoding +16. Implement Top p Sampling atop LLM for decoding +17. Implement Temperature Sampling atop LLM for decoding +18. Implement LoRA on a layer of an LLM +19. Mix two models to create a mixture of Experts +20. Apply SFT on SmolLM +21. Apply RLHF on SmolLM +22. Implement DPO based RLHF +23. Add continous batching to your LLM +24. Chunk Textual Data for Dense Passage Retreival +25. Implement Lage scale Training => 5D Parallelism **What's cool? ๐Ÿš€** - **Diverse Questions**: Covers beginner to advanced PyTorch concepts (e.g., tensors, autograd, CNNs, GANs, and more). diff --git a/llm/BPE-q3.ipynb b/llm/BPE-q3.ipynb new file mode 100644 index 0000000..ce3d058 --- /dev/null +++ b/llm/BPE-q3.ipynb @@ -0,0 +1,147 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "081a9dd1", + "metadata": {}, + "source": [ + "## Problem: Write a Byte Pain Encoder in Python\n", + "\n", + "### Problem Statement\n", + "Implement a **Transformer model** in PyTorch by completing the required sections. The model should consist of an embedding layer, a Transformer encoder, and an output layer for sequence processing and prediction.\n", + "\n", + "### Requirements\n", + "1. **Define the Transformer Model Architecture**:\n", + " - **Embedding Layer**:\n", + " - Implement a layer to transform input data into a higher-dimensional space.\n", + " - Use a `torch.nn.Linear` or `torch.nn.Embedding` layer to create embeddings from the input.\n", + " - **Transformer Encoder**:\n", + " - Use `torch.nn.TransformerEncoder` or `torch.nn.Transformer` to process sequences with attention.\n", + " - Configure parameters such as the number of attention heads and encoder layers.\n", + " - **Output Layer**:\n", + " - Add a fully connected (linear) layer to reduce the transformer's sequence output into the desired output dimension.\n", + "\n", + "2. **Implement the Forward Method**:\n", + " - Map the input to the higher-dimensional space using the embedding layer.\n", + " - Pass the transformed input through the Transformer encoder.\n", + " - Use the output layer to convert the encoded sequence into predictions.\n", + "\n", + "### Constraints\n", + "- Handle input padding correctly for variable-length sequences.\n", + "- Ensure compatibility with batch processing by correctly shaping input and output tensors.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89f09999", + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict, Counter\n", + "\n", + "def get_vocab(corpus):\n", + " \"\"\"Creates a vocabulary with words split into characters and a special end-of-word token.\"\"\"\n", + " vocab = Counter()\n", + " for word in corpus:\n", + " tokens = list(word) + ['']\n", + " vocab[tuple(tokens)] += 1\n", + " return vocab\n", + "\n", + "def get_stats(vocab):\n", + " \"\"\"Counts frequency of adjacent symbol pairs.\"\"\"\n", + " pairs = defaultdict(int)\n", + " for word, freq in vocab.items():\n", + " for i in range(len(word) - 1):\n", + " pairs[(word[i], word[i + 1])] += freq\n", + " return pairs\n", + "\n", + "def merge_vocab(pair, vocab):\n", + " \"\"\"Merges the most frequent pair into a single symbol.\"\"\"\n", + " new_vocab = {}\n", + " bigram = ' '.join(pair)\n", + " replacement = ''.join(pair)\n", + " for word, freq in vocab.items():\n", + " word_str = ' '.join(word)\n", + " # Replace bigram with merged symbol\n", + " new_word_str = word_str.replace(bigram, replacement)\n", + " new_vocab[tuple(new_word_str.split())] = freq\n", + " return new_vocab\n", + "\n", + "def byte_pair_encoding(corpus, num_merges=10):\n", + " \"\"\"Performs BPE on a corpus.\"\"\"\n", + " vocab = get_vocab(corpus)\n", + " merges = []\n", + " for _ in range(num_merges):\n", + " pairs = get_stats(vocab)\n", + " if not pairs:\n", + " break\n", + " best = max(pairs, key=pairs.get)\n", + " vocab = merge_vocab(best, vocab)\n", + " merges.append(best)\n", + " print(f\"Merge {_ + 1}: {best}\")\n", + " return vocab, merges\n", + "\n", + "# Example usage\n", + "corpus = [\"low\", \"lowest\", \"newer\", \"wider\"]\n", + "final_vocab, merge_operations = byte_pair_encoding(corpus, num_merges=10)\n", + "\n", + "print(\"\\nFinal Vocabulary:\")\n", + "for word in final_vocab:\n", + " print(' '.join(word), \":\", final_vocab[word])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e4638a1", + "metadata": {}, + "outputs": [], + "source": [ + "def test_get_vocab():\n", + " corpus = [\"test\"]\n", + " vocab = get_vocab(corpus)\n", + " assert vocab == {('t', 'e', 's', 't', ''): 1}\n", + " print(\"โœ“ test_get_vocab passed\")\n", + "\n", + "def test_get_stats():\n", + " vocab = {('t', 'e', 's', 't', ''): 1}\n", + " stats = get_stats(vocab)\n", + " expected = {\n", + " ('t', 'e'): 1,\n", + " ('e', 's'): 1,\n", + " ('s', 't'): 1,\n", + " ('t', ''): 1\n", + " }\n", + " assert stats == expected\n", + " print(\"โœ“ test_get_stats passed\")\n", + "\n", + "def test_merge_vocab():\n", + " vocab = {('t', 'e', 's', 't', ''): 1}\n", + " merged = merge_vocab(('e', 's'), vocab)\n", + " expected = {('t', 'es', 't', ''): 1}\n", + " assert merged == expected\n", + " print(\"โœ“ test_merge_vocab passed\")\n", + "\n", + "def test_bpe_sequence():\n", + " corpus = [\"low\", \"lower\", \"newest\", \"widest\"]\n", + " final_vocab, merges = byte_pair_encoding(corpus, num_merges=5)\n", + " assert isinstance(final_vocab, dict)\n", + " assert all(isinstance(pair, tuple) for pair in merges)\n", + " assert len(merges) == 5\n", + " print(\"โœ“ test_bpe_sequence passed\")\n", + "\n", + "# Run all tests\n", + "test_get_vocab()\n", + "test_get_\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c082efbc676feba5fd15336fcadf8f2e604ffc7a Mon Sep 17 00:00:00 2001 From: bargav Date: Wed, 21 May 2025 23:32:23 -0400 Subject: [PATCH 08/40] added smollm-q12 --- llm/smollm-q12.ipynb | 636 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 636 insertions(+) create mode 100644 llm/smollm-q12.ipynb diff --git a/llm/smollm-q12.ipynb b/llm/smollm-q12.ipynb new file mode 100644 index 0000000..abbc723 --- /dev/null +++ b/llm/smollm-q12.ipynb @@ -0,0 +1,636 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "746ece12", + "metadata": {}, + "source": [] + }, + { + "cell_type": "markdown", + "id": "64b63728", + "metadata": {}, + "source": [ + "## Question" + ] + }, + { + "cell_type": "markdown", + "id": "3a697924", + "metadata": {}, + "source": [ + "Code SmolLM-135M from scratch. (Architecture defined below)" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a4515dca", + "metadata": {}, + "outputs": [], + "source": [ + "# smolLM(\n", + "# (model): smolModel(\n", + "# (embed_tokens): Embedding(49152, 576)\n", + "# (layers): ModuleList(\n", + "# (0-29): 30 x LlamaDecoder(\n", + "# (self_attn): RopeAttention(\n", + "# (W_query): Linear(in_features=576, out_features=576, bias=False)\n", + "# (W_key): Linear(in_features=576, out_features=192, bias=False)\n", + "# (W_value): Linear(in_features=576, out_features=192, bias=False)\n", + "# (W_output): Linear(in_features=576, out_features=576, bias=False)\n", + "# (rotary_emb): RotaryEmbedder()\n", + "# )\n", + "# (mlp): MLP(\n", + "# (W_gate): Linear(in_features=576, out_features=1536, bias=False)\n", + "# (W_up): Linear(in_features=576, out_features=1536, bias=False)\n", + "# (W_down): Linear(in_features=1536, out_features=576, bias=False)\n", + "# (act_fn): SiLU()\n", + "# )\n", + "# (pre_attn_rmsnorm): RMSNorm()\n", + "# (pre_mlp_rmsnorm): RMSNorm()\n", + "# )\n", + "# )\n", + "# (norm): RMSNorm()\n", + "# )\n", + "# (lm_head): Linear(in_features=576, out_features=49152, bias=False)\n", + "# )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5933189", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "4d6e84d3", + "metadata": {}, + "source": [ + "## Solution" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3da31db3", + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "import torch\n", + "from torch import nn\n", + "\n", + "# Helper function to rotate the last half of a tensor\n", + "# Used in rotary positional embeddings to compute sine and cosine rotations\n", + "def rotate_half(x):\n", + " # Split tensor into two halves along the last dimension\n", + " x1 = x[..., : x.shape[-1] // 2]\n", + " x2 = x[..., x.shape[-1] // 2 :]\n", + " # Rotate: negate the second half and concatenate it with the first half\n", + " return torch.cat((-x2, x1), dim=-1)\n", + "\n", + "# Applies rotary positional embeddings to query (q) and key (k) tensors\n", + "# Uses sine and cosine positional encodings to enhance positional awareness\n", + "def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):\n", + " # Expand cos and sin tensors for broadcasting\n", + " cos = cos.unsqueeze(unsqueeze_dim)\n", + " sin = sin.unsqueeze(unsqueeze_dim)\n", + "\n", + " # Apply rotations to q and k using cos and sin\n", + " q_embed = (q * cos) + (rotate_half(q) * sin)\n", + " k_embed = (k * cos) + (rotate_half(k) * sin)\n", + " return q_embed, k_embed\n", + "\n", + "# Repeats key-value tensors for multiple attention heads\n", + "# Ensures compatibility between the number of attention heads and key-value heads\n", + "def repeat_kv(hidden_states, n_rep):\n", + " batch, num_key_value_heads, slen, head_dim = hidden_states.shape\n", + " # Expand the number of key-value heads by repeating them\n", + " hidden_states = hidden_states[:, :, None, :, :].expand(\n", + " batch, num_key_value_heads, n_rep, slen, head_dim\n", + " )\n", + " # Reshape to align with the expected multi-head attention format\n", + " return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)\n", + "\n", + "# Computes rotary positional embeddings for queries and keys\n", + "class RotaryEmbedder(nn.Module):\n", + " def __init__(self, dim, base):\n", + " super().__init__()\n", + " # Precompute frequency for sine/cosine embeddings\n", + " self.freq = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim))\n", + "\n", + " @torch.no_grad()\n", + " def forward(self, x):\n", + " # Generate positions (sequence indices) for the input\n", + " pos = torch.arange(x.shape[-2], dtype=torch.long)\n", + " # Compute angles for sine and cosine embeddings\n", + " angles = torch.einsum(\"p,f->pf\", pos.float(), self.freq).unsqueeze(dim=0)\n", + " # Duplicate angles for sine and cosine embeddings\n", + " emb = torch.cat((angles, angles), dim=-1)\n", + " # Return cosine and sine components of the positional embeddings\n", + " return emb.cos(), emb.sin()\n", + "\n", + "# Implements attention with rotary positional embeddings\n", + "class RopeAttention(nn.Module):\n", + " def __init__(self, config):\n", + " super().__init__()\n", + " # Model dimensions and attention configurations\n", + " self.hidden_size = config.hidden_size\n", + " self.num_heads = config.num_heads\n", + " self.head_dim = config.hidden_size // self.num_heads\n", + " self.kv_heads = config.kv_heads # Number of key-value heads\n", + " self.rope_theta = 10000.0 # Scaling factor for rotary embeddings\n", + "\n", + " # Linear projections for queries, keys, values, and output\n", + " self.W_query = nn.Linear(config.hidden_size, self.num_heads * self.head_dim, bias=False)\n", + " self.W_key = nn.Linear(config.hidden_size, self.kv_heads * self.head_dim, bias=False)\n", + " self.W_value = nn.Linear(config.hidden_size, self.kv_heads * self.head_dim, bias=False)\n", + " self.W_output = nn.Linear(config.hidden_size, config.hidden_size, bias=False)\n", + "\n", + " # Rotary embedding generator\n", + " self.rotary_emb = RotaryEmbedder(base=self.rope_theta, dim=self.head_dim)\n", + "\n", + " def forward(self, hidden_states: torch.Tensor, attention_mask=None):\n", + " # Input dimensions: (batch_size, seq_len, hidden_size)\n", + " b, q, _ = hidden_states.size()\n", + "\n", + " # Project input hidden states into queries, keys, and values\n", + " q_states = self.W_query(hidden_states)\n", + " k_states = self.W_key(hidden_states)\n", + " v_states = self.W_value(hidden_states)\n", + "\n", + " # Reshape and transpose for multi-head attention\n", + " q_states = q_states.view(b, q, self.num_heads, self.head_dim).transpose(1, 2)\n", + " k_states = k_states.view(b, q, self.kv_heads, self.head_dim).transpose(1, 2)\n", + " v_states = v_states.view(b, q, self.kv_heads, self.head_dim).transpose(1, 2)\n", + "\n", + " # Compute rotary positional embeddings\n", + " cos, sin = self.rotary_emb(q_states)\n", + " # Apply positional embeddings to queries and keys\n", + " q_states, k_states = apply_rotary_pos_emb(q_states, k_states, cos, sin)\n", + "\n", + " # Repeat key and value tensors to match the number of query heads\n", + " __kv_groups = self.num_heads // self.kv_heads\n", + " k_states = repeat_kv(k_states, __kv_groups)\n", + " v_states = repeat_kv(v_states, __kv_groups)\n", + "\n", + " # Compute attention scores (scaled dot-product attention)\n", + " attn_weights = torch.matmul(q_states, k_states.transpose(2, 3)) / math.sqrt(self.head_dim)\n", + "\n", + " # Add attention mask (e.g., for causal or padding masking)\n", + " attn_weights = attn_weights + attention_mask\n", + "\n", + " # Normalize attention weights using softmax\n", + " attn_weights = nn.functional.softmax(attn_weights, dim=-1)\n", + " # Apply dropout to attention weights\n", + " attn_weights = nn.functional.dropout(attn_weights, 0)\n", + "\n", + " # Compute attention output\n", + " attn_output = torch.matmul(attn_weights, v_states)\n", + " # Reshape and transpose back to original format\n", + " attn_output = attn_output.transpose(1, 2).contiguous()\n", + " attn_output = attn_output.reshape(b, q, -1)\n", + "\n", + " # Project the attention output back to the hidden size\n", + " attn_output = self.W_output(attn_output)\n", + "\n", + " # Return the final attention output\n", + " return attn_output" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "574659e2", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "from torch import nn\n", + "\n", + "# Multi-Layer Perceptron (MLP) class\n", + "class MLP(nn.Module):\n", + " def __init__(self, hidden_size, intermediate_size):\n", + " \"\"\"\n", + " Initialize an MLP with a gating mechanism and non-linear activation.\n", + "\n", + " Args:\n", + " hidden_size (int): The size of the input and output embeddings.\n", + " intermediate_size (int): The size of the hidden layer.\n", + " \"\"\"\n", + " super().__init__()\n", + " self.hidden_size = hidden_size\n", + " self.intermediate_size = intermediate_size\n", + "\n", + " # Linear layers for the gated MLP structure\n", + " self.W_gate = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)\n", + " self.W_up = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)\n", + " self.W_down = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)\n", + "\n", + " # Activation function (SiLU)\n", + " self.act_fn = torch.nn.modules.activation.SiLU()\n", + "\n", + " def forward(self, x):\n", + " \"\"\"\n", + " Forward pass for the gated MLP.\n", + " \n", + " Args:\n", + " x (torch.Tensor): Input tensor of shape (batch_size, seq_len, hidden_size).\n", + " \n", + " Returns:\n", + " torch.Tensor: Output tensor of shape (batch_size, seq_len, hidden_size).\n", + " \"\"\"\n", + " # Apply gating mechanism and project back to hidden size\n", + " down_proj = self.W_down(self.act_fn(self.W_gate(x)) * self.W_up(x))\n", + " return down_proj\n", + "\n", + "\n", + "# RMSNorm class (Root Mean Square Normalization)\n", + "class RMSNorm(nn.Module):\n", + " def __init__(self, hidden_size, eps=1e-6):\n", + " \"\"\"\n", + " Initialize RMSNorm.\n", + "\n", + " Args:\n", + " hidden_size (int): The size of the input embeddings.\n", + " eps (float): A small value to prevent division by zero.\n", + " \"\"\"\n", + " super().__init__()\n", + " self.weight = nn.Parameter(torch.ones(hidden_size)) # Learnable scaling factor\n", + " self.variance_epsilon = eps\n", + "\n", + " def forward(self, hidden_states):\n", + " \"\"\"\n", + " Forward pass for RMSNorm.\n", + "\n", + " Args:\n", + " hidden_states (torch.Tensor): Input tensor of shape (batch_size, seq_len, hidden_size).\n", + "\n", + " Returns:\n", + " torch.Tensor: Normalized tensor.\n", + " \"\"\"\n", + " # Calculate variance along the last dimension (hidden size)\n", + " variance = hidden_states.pow(2).mean(-1, keepdim=True)\n", + "\n", + " # Normalize and scale\n", + " hidden_states = hidden_states * torch.rsqrt(variance + self.variance_epsilon)\n", + " return self.weight * hidden_states\n", + "\n", + "\n", + "# Rotary Embedder class\n", + "class RotaryEmbedder(nn.Module):\n", + " def __init__(self, dim, base):\n", + " \"\"\"\n", + " Initialize rotary embeddings for positional encodings.\n", + "\n", + " Args:\n", + " dim (int): Dimensionality of embeddings (half the hidden size per head).\n", + " base (float): Base frequency for rotary embeddings.\n", + " \"\"\"\n", + " super().__init__()\n", + " # Frequency for rotary embeddings\n", + " self.freq = 1.0 / (base ** (torch.arange(0, dim, 2, dtype=torch.float32) / dim))\n", + "\n", + " def forward(self, x):\n", + " \"\"\"\n", + " Compute cosine and sine embeddings for rotary position encoding.\n", + "\n", + " Args:\n", + " x (torch.Tensor): Input tensor of shape (batch_size, seq_len, dim).\n", + "\n", + " Returns:\n", + " Tuple[torch.Tensor, torch.Tensor]: Cosine and sine embeddings.\n", + " \"\"\"\n", + " pos = torch.arange(x.shape[-2], dtype=torch.float32) # Sequence positions\n", + "\n", + " # Calculate angular frequencies\n", + " angles = torch.einsum(\"p,f->pf\", pos, self.freq).unsqueeze(0)\n", + " \n", + " # Create cosine and sine embeddings\n", + " emb = torch.cat((angles, angles), dim=-1)\n", + " return emb.cos(), emb.sin()\n", + "\n", + "\n", + "# LlamaDecoder class\n", + "class LlamaDecoder(nn.Module):\n", + " def __init__(self, config):\n", + " \"\"\"\n", + " Initialize the LlamaDecoder layer with attention and MLP sublayers.\n", + "\n", + " Args:\n", + " config: Configuration object containing model parameters.\n", + " \"\"\"\n", + " super().__init__()\n", + " # Attention mechanism with rotary embeddings\n", + " self.self_attn = RopeAttention(config)\n", + "\n", + " # Feedforward neural network (MLP)\n", + " self.mlp = MLP(hidden_size=config.hidden_size, intermediate_size=config.intermediate_size)\n", + "\n", + " # Pre-layer normalization (RMSNorm) for attention and MLP\n", + " self.pre_attn_rmsnorm = RMSNorm(config.hidden_size, eps=1e-05)\n", + " self.pre_mlp_rmsnorm = RMSNorm(config.hidden_size, eps=1e-05)\n", + "\n", + " def forward(self, hidden_states, attention_mask):\n", + " \"\"\"\n", + " Forward pass for the LlamaDecoder layer.\n", + "\n", + " Args:\n", + " hidden_states (torch.Tensor): Input tensor of shape (batch_size, seq_len, hidden_size).\n", + " attention_mask (torch.Tensor): Mask to prevent attention to certain positions.\n", + "\n", + " Returns:\n", + " Tuple[torch.Tensor]: Output tensor of shape (batch_size, seq_len, hidden_size).\n", + " \"\"\"\n", + " # Residual connection for attention sublayer\n", + " residual = hidden_states\n", + "\n", + " # Apply RMSNorm before attention\n", + " hidden_states = self.pre_attn_rmsnorm(hidden_states)\n", + "\n", + " # Generate a triangular attention mask (causal masking)\n", + " attention_mask = torch.triu(torch.full((attention_mask.shape[-1], attention_mask.shape[-1]),\n", + " fill_value=float('-inf')), diagonal=1)\n", + "\n", + " # Apply self-attention\n", + " hidden_states = self.self_attn(\n", + " hidden_states=hidden_states,\n", + " attention_mask=attention_mask,\n", + " )\n", + "\n", + " # Add residual connection\n", + " hidden_states += residual\n", + "\n", + " # Residual connection for MLP sublayer\n", + " residual = hidden_states\n", + "\n", + " # Apply RMSNorm before MLP\n", + " hidden_states = self.pre_mlp_rmsnorm(hidden_states)\n", + "\n", + " # Pass through MLP\n", + " hidden_states = self.mlp(hidden_states)\n", + "\n", + " # Add residual connection\n", + " hidden_states += residual\n", + "\n", + " # Return the output hidden states\n", + " return hidden_states," + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "f2d2f9a1", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "# The main model containing the embedding layer, decoder stack, and normalization layer\n", + "class smolModel(nn.Module):\n", + " def __init__(self, config):\n", + " super().__init__()\n", + " # Token embedding layer: maps input tokens to dense representations\n", + " self.embed_tokens = nn.Embedding(\n", + " num_embeddings=config.vocab_size,\n", + " embedding_dim=config.hidden_size\n", + " )\n", + " # Stack of decoder layers (LlamaDecoder) defined by the configuration\n", + " self.layers = nn.ModuleList([\n", + " LlamaDecoder(config) for _ in range(config.num_hidden_layers)\n", + " ])\n", + " # RMSNorm: final layer normalization applied to hidden states\n", + " self.norm = RMSNorm(config.hidden_size, eps=1e-05)\n", + "\n", + " def forward(self, input_ids=None, attention_mask=None):\n", + " # Convert input token IDs to dense embeddings\n", + " inputs_embeds = self.embed_tokens(input_ids)\n", + " hidden_states = inputs_embeds\n", + "\n", + " # Pass embeddings through each decoder layer in the stack\n", + " for decoder_layer in self.layers:\n", + " layer_outputs = decoder_layer(\n", + " hidden_states,\n", + " attention_mask=attention_mask, # Pass the attention mask\n", + " )\n", + " # Update hidden states with the output of the current decoder layer\n", + " hidden_states = layer_outputs[0]\n", + "\n", + " # Apply final layer normalization to the hidden states\n", + " hidden_states = self.norm(hidden_states)\n", + "\n", + " # Return the processed hidden states\n", + " return hidden_states\n", + "\n", + "\n", + "# The complete language model, combining smolModel and a language modeling head (lm_head)\n", + "class smolLM(nn.Module):\n", + " def __init__(self, config):\n", + " super().__init__()\n", + " # Core model containing embeddings and decoder stack\n", + " self.model = smolModel(config)\n", + " # Language modeling head: projects hidden states to vocabulary logits\n", + " self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)\n", + "\n", + " # Tie weights between the embedding layer and lm_head\n", + " self.tie_weights()\n", + "\n", + " def tie_weights(self):\n", + " # Ensures the lm_head shares weights with the embedding layer\n", + " # This is a common optimization for language models\n", + " self.lm_head.weight = self.model.embed_tokens.weight\n", + "\n", + " def forward(self, input_ids, attention_mask):\n", + " # Pass inputs through the core model to obtain hidden states\n", + " outputs = self.model(\n", + " input_ids=input_ids,\n", + " attention_mask=attention_mask,\n", + " )\n", + "\n", + " # Obtain hidden states from the model's output\n", + " hidden_states = outputs\n", + "\n", + " # Pass hidden states through the language modeling head\n", + " logits = self.lm_head(hidden_states)\n", + " # Ensure logits are returned in float for numerical stability\n", + " logits = logits.float()\n", + "\n", + " # Return the output as a dictionary containing logits\n", + " return {'logits': logits}\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5083c3ac", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "e796bcb0", + "metadata": {}, + "source": [ + "## Test" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "486d9159", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + ">>>>>>>>>>>>>>>>>>>>\n", + "\tPrompt\n", + "<<<<<<<<<<<<<<<<<<<<\n", + "Given the following film movie by a critic, rate it out of 10. Respond in a single number.\n", + "\n", + "The movie started off extremely well, but just got worse after that.\n", + "The storyline was all over the place and everyone acted terribly.\n", + " 10/10 would not recommend! \n", + "\n", + " \n", + "\n", + "\n", + ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", + "\tModel_A Generation\n", + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + "1\n", + "\n", + "\n", + ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", + "\tModel_B Generation\n", + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", + "1\n", + " bright, but itโ€™s not without its challenges. One of the biggest challenges is the lack of regulation and oversight. AI systems are often developed and deployed without the necessary safeguards in place to ensure they are safe and ethical. This lack of regulation can\n" + ] + } + ], + "source": [ + "from transformers import AutoTokenizer, AutoModelForCausalLM\n", + "\n", + "\n", + "# Libraries\n", + "import torch\n", + "import torch.nn.functional as F\n", + "from torch import nn\n", + "import math\n", + "\n", + "########################## HELPER FUNCTIONS ######################\n", + "\n", + "def __generate(model, inputs, num_tokens, tokenizer, max_length=50):\n", + " collect = []\n", + " for _ in range(num_tokens):\n", + " output = model(**inputs)\n", + " output_id = torch.argmax(output['logits'][0, -1]).item()\n", + " collect.append(output_id)\n", + " if output_id == tokenizer.eos_token_id or len(collect) >= max_length:\n", + " break\n", + " # Update input_ids and attention_mask\n", + " new_token = torch.tensor([output_id], device=inputs['input_ids'].device)\n", + " inputs['input_ids'] = torch.cat([inputs['input_ids'][0], new_token]).unsqueeze(0)\n", + " inputs['attention_mask'] = F.pad(inputs['attention_mask'], (0, 1), value=1)\n", + " return tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(collect))\n", + "\n", + "\n", + "def check_solution(prompt, num_tokens, model_A, model_B, tokenizer, max_length=50):\n", + " print(f\"{'>'*20}\\n\\tPrompt\\n{'<'*20}\\n{prompt}\\n\\n\")\n", + " \n", + " model_inputs = tokenizer(prompt, return_tensors='pt')\n", + " \n", + " try:\n", + " print(f\"{'>'*30}\\n\\tModel_A Generation\\n{'<'*30}\")\n", + " print(__generate(model_A, model_inputs, num_tokens, tokenizer, max_length))\n", + " except Exception as e:\n", + " print(f\"Error with Model_A: {e}\")\n", + " \n", + " try:\n", + " model_inputs = tokenizer(prompt, return_tensors='pt')\n", + " print(f\"\\n\\n{'>'*30}\\n\\tModel_B Generation\\n{'<'*30}\")\n", + " print(__generate(model_B, model_inputs, num_tokens, tokenizer, max_length))\n", + " except Exception as e:\n", + " print(f\"Error with Model_B: {e}\")\n", + "\n", + "\n", + "class smolConfig:\n", + " vocab_size = 49152\n", + " hidden_size = 576\n", + " intermediate_size = 1536\n", + " num_hidden_layers = 30\n", + " num_heads = 9\n", + " kv_heads = 3\n", + "\n", + "import torch\n", + "\n", + "\n", + "# Load tokenizer and reference model\n", + "checkpoint = \"HuggingFaceTB/SmolLM-135M\"\n", + "tokenizer = AutoTokenizer.from_pretrained(checkpoint)\n", + "reference_model = AutoModelForCausalLM.from_pretrained(checkpoint)\n", + "\n", + "# Initialize smolLM\n", + "config = smolConfig()\n", + "test_model = smolLM(config)\n", + "\n", + "# Load weights\n", + "state_dict = torch.load(\"../../temp/BareBones_SmolLM-135M.pt\")\n", + "test_model.load_state_dict(state_dict, strict=False)\n", + "\n", + "check_solution(prompt=\"Given the following film movie by a critic, rate it out of 10. Respond in a single number.\\n\\nThe movie started off extremely well, but just got worse after that.\\nThe storyline was all over the place and everyone acted terribly.\\n 10/10 would not recommend! \\n\\n \",\n", + " num_tokens=1,\n", + " model_A=reference_model,\n", + " model_B=test_model, tokenizer=tokenizer)\n", + "\n", + "prompt = \"The future of AI is\"\n", + "inputs = tokenizer(prompt, return_tensors=\"pt\")\n", + "print(__generate(test_model, inputs, num_tokens=50, tokenizer=tokenizer))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6492e7f", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6bb515f1", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "llm_env", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From eaae575a63d55de572c50ac079fe75fab69e75be Mon Sep 17 00:00:00 2001 From: bargav Date: Wed, 21 May 2025 23:34:42 -0400 Subject: [PATCH 09/40] added smollm-q12 --- llm/smollm-q12.ipynb | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/llm/smollm-q12.ipynb b/llm/smollm-q12.ipynb index abbc723..fe73296 100644 --- a/llm/smollm-q12.ipynb +++ b/llm/smollm-q12.ipynb @@ -204,7 +204,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "574659e2", "metadata": {}, "outputs": [], @@ -383,7 +383,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "id": "f2d2f9a1", "metadata": {}, "outputs": [], @@ -481,10 +481,18 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 5, "id": "486d9159", "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/bargav/anaconda3/envs/llm_env/lib/python3.13/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", + " from .autonotebook import tqdm as notebook_tqdm\n" + ] + }, { "name": "stdout", "output_type": "stream", @@ -510,8 +518,7 @@ ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", "\tModel_B Generation\n", "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", - "1\n", - " bright, but itโ€™s not without its challenges. One of the biggest challenges is the lack of regulation and oversight. AI systems are often developed and deployed without the necessary safeguards in place to ensure they are safe and ethical. This lack of regulation can\n" + "1\n" ] } ], @@ -589,10 +596,7 @@ " num_tokens=1,\n", " model_A=reference_model,\n", " model_B=test_model, tokenizer=tokenizer)\n", - "\n", - "prompt = \"The future of AI is\"\n", - "inputs = tokenizer(prompt, return_tensors=\"pt\")\n", - "print(__generate(test_model, inputs, num_tokens=50, tokenizer=tokenizer))" + "\n" ] }, { From 7e136228799bcaa7586a0196c6a52d5b839ca246 Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 22:49:07 -0400 Subject: [PATCH 10/40] Update attention-q4.ipynb --- llm/attention-q4.ipynb | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/llm/attention-q4.ipynb b/llm/attention-q4.ipynb index 3590d80..2a18a68 100644 --- a/llm/attention-q4.ipynb +++ b/llm/attention-q4.ipynb @@ -6,18 +6,34 @@ "source": [ "# Implement Attention from Scratch\n", "### Problem Statement\n", + "Implement a **Scaled Dot-Product Attention** mechanism from scratch using PyTorch. Your mission (should you choose to accept it) is to replicate what PyTorch's built-in `scaled_dot_product_attention` does โ€” manually. This core component is essential in Transformer architectures and helps models focus on relevant parts of a sequence. You'll test your implementation against PyTorch's native one to ensure you nailed it.\n", "\n", "\n", "### Requirements\n", - "1. \n", + "1. **Define the Function**:\n", + " - Create a function `scaled_dot_product_attention(q, k, v, mask=None)` that:\n", + " - Computes attention scores via the dot product of query and key vectors.\n", + " - Scales the scores using the square root of the key dimension.\n", + " - Applies an optional mask to the scores.\n", + " - Applies softmax to convert scores into attention weights.\n", + " - Uses these weights to compute a weighted sum of values (V).\n", + "\n", + "2. **Test Your Work**:\n", + " - Use sample tensors for query (Q), key (K), and value (V).\n", + " - Compare the result of your custom implementation with PyTorch's `F.scaled_dot_product_attention` using an `assert` to check numerical accuracy.\n", + "\n", "\n", "### Constraints\n", - "- \n", + "- โŒ Do NOT use `F.scaled_dot_product_attention` inside your custom function โ€” that defeats the whole point.\n", + "- โœ… Your implementation must handle **batch dimensions** correctly.\n", + "- โœ… Support optional **masking** for future tokens or padding.\n", + "- โœ… Use only PyTorch ops โ€” no cheating with external attention libs.\n", + "\n", "\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", + " Use `torch.matmul()` to compute dot products and `F.softmax()` for the final attention weights. The mask (if used) should be applied **before** the softmax using `masked_fill`.\n", "
\n" ] }, From 851501bf0d0006eb01382976950ba849396f6f7c Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 22:58:12 -0400 Subject: [PATCH 11/40] Update embeddings-q2.ipynb --- llm/embeddings-q2.ipynb | 60 +++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/llm/embeddings-q2.ipynb b/llm/embeddings-q2.ipynb index 13581ac..d598930 100644 --- a/llm/embeddings-q2.ipynb +++ b/llm/embeddings-q2.ipynb @@ -4,23 +4,67 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Create embeddings out of an LLM\n", - "### Problem Statement\n", + "# ๐Ÿง  Create Embeddings out of an LLM\n", "\n", + "### ๐Ÿงฉ Problem Statement\n", + "Your mission, should you choose to accept it, is to extract **meaningful sentence-level embeddings** using a pre-trained **causal language model (SmolLM2-135M)** on Amazon Reviews.\n", "\n", - "### Requirements\n", - "1. \n", + "You're working with a **generative language model**, but youโ€™re not here to generate Shakespeare. Instead, youโ€™ll tap into its **hidden states** to get semantic embeddings that capture the essence of a review โ€” the good, the bad, and the brutally honest.\n", "\n", - "### Constraints\n", - "- \n", + "---\n", "\n", + "### โœ… Requirements\n", "\n", + "1. **Load and Tokenize Text**\n", + " - Use the `McAuley-Lab/Amazon-Reviews-2023` dataset (subset: `raw_review_All_Beauty`).\n", + " - Load ~10 sample reviews for testing.\n", + " - Tokenize them using `\"HuggingFaceTB/SmolLM2-135M\"` tokenizer.\n", "\n", + "2. **Extract Embeddings**\n", + " - Run the tokenized batch through the model with `output_hidden_states=True`.\n", + " - Access the **last hidden layer** from `outputs.hidden_states[-1]`.\n", + "\n", + "3. **Compute Sentence Embeddings**\n", + " - Options:\n", + " - If the model uses a classification token (e.g., `[CLS]`), extract its embedding.\n", + " - For causal models (which typically donโ€™t), **average the token embeddings** from the final layer, **excluding padding tokens**.\n", + "\n", + "4. **Display the Result**\n", + " - Show the shape of your final sentence embedding tensor.\n", + " - Print at least one sentence-level embedding to verify everything worked.\n", + "\n", + "---\n", + "\n", + "### ๐Ÿšซ Constraints\n", + "\n", + "- โŒ Do **not** use sentence-transformers or pre-built embedding tools like `bert-as-service`.\n", + "- โŒ Do **not** generate text (no `.generate()`).\n", + "- โœ… Use only Hugging Face's `AutoModelForCausalLM` and `AutoTokenizer`.\n", + "- โœ… Exclude padding tokens when computing average embeddings.\n", + "- โœ… Ensure everything runs on `cuda` if available.\n", + "\n", + "---\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", - "
\n" + "\n", + "```python\n", + "# Run model with hidden states\n", + "outputs = model(**tokenized_inputs, output_hidden_states=True, return_dict=True)\n", + "\n", + "# Get the last hidden layer (batch_size, seq_len, hidden_dim)\n", + "last_hidden = outputs.hidden_states[-1]\n", + "\n", + "# Use the attention mask to avoid averaging over padding\n", + "attention_mask = tokenized_inputs['attention_mask'] # (batch_size, seq_len)\n", + "\n", + "# Compute masked average: zero out padding tokens\n", + "masked_embeddings = last_hidden * attention_mask.unsqueeze(-1) # broadcast mask\n", + "summed = masked_embeddings.sum(dim=1) # sum across tokens\n", + "count = attention_mask.sum(dim=1, keepdim=True) # count of non-padding tokens\n", + "\n", + "# Final sentence-level embeddings\n", + "sentence_embeddings = summed / count # (batch_size, hidden_dim)\n" ] }, { From 469bce5073f7c0d6a98f65192b049c65d2cc3e5f Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:03:06 -0400 Subject: [PATCH 12/40] Update rope-q8.ipynb --- llm/rope-q8.ipynb | 50 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/llm/rope-q8.ipynb b/llm/rope-q8.ipynb index 0cd7b52..b13cf26 100644 --- a/llm/rope-q8.ipynb +++ b/llm/rope-q8.ipynb @@ -5,20 +5,56 @@ "metadata": {}, "source": [ "# Implement ROPE from Scratch\n", - "### Problem Statement\n", + "# ๐Ÿ” Rotary Positional Embeddings in PyTorch\n", "\n", + "### ๐Ÿง  Problem Statement\n", + "Transformers need a sense of **order**, but vanilla attention mechanisms are position-agnostic. Positional encodings help inject this order-awareness into the model. \n", "\n", - "### Requirements\n", - "1. \n", + "Your mission is to implement **Rotary Positional Embeddings (RoPE)** from scratch โ€” a newer and slicker technique that rotates the query and key vectors instead of simply adding sine-cosine vectors. This method preserves attention efficiency while enabling better generalization for long sequences.\n", "\n", - "### Constraints\n", - "- \n", + "---\n", "\n", + "### โœ… Requirements\n", + "\n", + "1. **Implement the Rotary Module**\n", + " - Construct a `Rotary` class to compute sinusoidal frequencies.\n", + " - Precompute and cache `cos` and `sin` values per sequence length.\n", + " - Register these as buffers to keep them on the correct device.\n", + "\n", + "2. **Define Rotation Helpers**\n", + " - `rotate_half(x)` splits and rotates half the dimensions of a tensor.\n", + " - `apply_rotary_pos_emb(q, k, cos, sin)` applies these rotations to Q and K.\n", + "\n", + "3. **Simulate Usage**\n", + " - Create synthetic tensors for Q, K, V.\n", + " - Generate rotary embeddings using the custom `Rotary` module.\n", + " - Apply rotary embeddings to Q and K.\n", + "\n", + "4. **Verify Dimensions**\n", + " - Final shapes should align with expected shapes for attention modules.\n", + " - Confirm RoPE is applied before dot-product attention would normally occur.\n", + "\n", + "---\n", + "\n", + "### ๐Ÿ“ Constraints\n", + "\n", + "- โœ… Use only PyTorch โ€” no Fairseq or HuggingFace positional modules.\n", + "- โœ… Must support dynamic sequence lengths and cache embeddings per sequence.\n", + "- โœ… Should handle odd/even dimensional splits correctly.\n", + "- โŒ Do **not** manually plug in Fairseqโ€™s `SinusoidalPositionalEmbedding`.\n", + "\n", + "---\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", - "
\n" + " - Use `torch.einsum(\"i,j->ij\", t, inv_freq)` to compute frequency pairs.\n", + " - Cache the cosine and sine values in the `Rotary` class using `self.register_buffer()`.\n", + " - The `rotate_half(x)` function should split `x` into two halves and rotate them: `[-x2, x1]`.\n", + " - Apply the rotary transformation using: \n", + " `(q * cos) + (rotate_half(q) * sin)` \n", + " and similarly for `k`.\n", + " - Remember to broadcast `cos` and `sin` to match the shape of `q` and `k`.\n", + "" ] }, { From 700be164ed104ca257e4c00ab04ad5f6f3b8cc7c Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:06:02 -0400 Subject: [PATCH 13/40] Update embeddings-q2.ipynb --- llm/embeddings-q2.ipynb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llm/embeddings-q2.ipynb b/llm/embeddings-q2.ipynb index d598930..713dc6a 100644 --- a/llm/embeddings-q2.ipynb +++ b/llm/embeddings-q2.ipynb @@ -4,16 +4,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# ๐Ÿง  Create Embeddings out of an LLM\n", + "# Create Embeddings out of an LLM\n", "\n", - "### ๐Ÿงฉ Problem Statement\n", + "### Problem Statement\n", "Your mission, should you choose to accept it, is to extract **meaningful sentence-level embeddings** using a pre-trained **causal language model (SmolLM2-135M)** on Amazon Reviews.\n", "\n", "You're working with a **generative language model**, but youโ€™re not here to generate Shakespeare. Instead, youโ€™ll tap into its **hidden states** to get semantic embeddings that capture the essence of a review โ€” the good, the bad, and the brutally honest.\n", "\n", "---\n", "\n", - "### โœ… Requirements\n", + "### Requirements\n", "\n", "1. **Load and Tokenize Text**\n", " - Use the `McAuley-Lab/Amazon-Reviews-2023` dataset (subset: `raw_review_All_Beauty`).\n", @@ -35,7 +35,7 @@ "\n", "---\n", "\n", - "### ๐Ÿšซ Constraints\n", + "### Constraints\n", "\n", "- โŒ Do **not** use sentence-transformers or pre-built embedding tools like `bert-as-service`.\n", "- โŒ Do **not** generate text (no `.generate()`).\n", From ba43be71515a3194c507d02dcf67f6987ae33c8a Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:06:05 -0400 Subject: [PATCH 14/40] Update sinusoidal-q7.ipynb --- llm/sinusoidal-q7.ipynb | 44 +++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/llm/sinusoidal-q7.ipynb b/llm/sinusoidal-q7.ipynb index 2895be9..62422ae 100644 --- a/llm/sinusoidal-q7.ipynb +++ b/llm/sinusoidal-q7.ipynb @@ -5,20 +5,52 @@ "metadata": {}, "source": [ "# Implement Attention from Scratch\n", - "### Problem Statement\n", + "### Problem Statement\n", + "Transformers are order-agnostic โ€” they see tokens like goldfish: no sense of sequence. To inject **position awareness** into the model, we use **Sinusoidal Positional Embeddings**, where each position in the sequence gets a unique deterministic vector. These vectors are computed using sine and cosine waves at different frequencies.\n", "\n", + "Your task is to implement the sinusoidal position encoding mechanism from scratch using PyTorch โ€” no cheating with built-ins from `fairseq` or Hugging Face.\n", "\n", - "### Requirements\n", - "1. \n", + "---\n", + "\n", + "### Requirements\n", + "\n", + "1. **Define the Sinusoidal Embedding Class**\n", + " - Implement a `SinusoidalPositionalEmbedding` class inheriting from `nn.Module`.\n", + " - Initialize with `max_seq_len` and `d_model`.\n", + " - Create a tensor `pe` of shape `(max_seq_len, d_model)` filled with sine and cosine encodings:\n", + " - `sin(position * ฯ‰)` for even indices\n", + " - `cos(position * ฯ‰)` for odd indices\n", + "\n", + "2. **Register as Buffer**\n", + " - Use `self.register_buffer(\"pe\", pe)` to store `pe` without treating it as a trainable parameter.\n", + "\n", + "3. **Generate Encodings**\n", + " - On calling `forward(x)`, return the slice of positional encodings matching the sequence length of `x`.\n", + "\n", + "4. **Test the Embeddings**\n", + " - Initialize the embedding class with `max_seq_len = 100` and `d_model = 64`.\n", + " - Pass a sequence of length 50 to verify the returned shape is `(1, 50, 64)`.\n", + "\n", + "---\n", "\n", "### Constraints\n", - "- \n", "\n", + "- โœ… Do not use Hugging Face, Fairseq, or built-in PyTorch modules for position encoding.\n", + "- โœ… Ensure the `pe` tensor is not a trainable parameter.\n", + "- โœ… Support any sequence length up to `max_seq_len`.\n", + "- โŒ Do not inject these embeddings directly into token embeddings yet โ€” this is just the embedding module.\n", + "\n", + "---\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", - "
\n" + "\n", + " - Use `torch.arange(0, max_seq_len).unsqueeze(1)` to create position indices.\n", + " - Compute frequencies with `torch.exp(torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model))`.\n", + " - Alternate `sin` and `cos` values for even and odd embedding dimensions.\n", + " - When returning the embedding in `forward`, use `.unsqueeze(0)` to broadcast over the batch dimension.\n", + "\n", + "" ] }, { From a387e955bf81b23e13a86ee032fff09774729c73 Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:07:45 -0400 Subject: [PATCH 15/40] Update grouped-query-attention.ipynb Added the problem statements and descriptions --- llm/grouped-query-attention.ipynb | 50 ++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/llm/grouped-query-attention.ipynb b/llm/grouped-query-attention.ipynb index ed2bb30..6ce4f79 100644 --- a/llm/grouped-query-attention.ipynb +++ b/llm/grouped-query-attention.ipynb @@ -5,20 +5,56 @@ "metadata": {}, "source": [ "# Implement Attention from Scratch\n", - "### Problem Statement\n", + "### ๐Ÿง  Problem Statement\n", + "Standard Multi-Head Attention (MHA) assigns a separate query, key, and value projection to each attention head. But thatโ€™s not always the most efficient approach. \n", "\n", + "Enter **Grouped Query Attention (GQA)** โ€” a clever mechanism where you use more query heads than key-value heads. This reduces compute/memory costs while still allowing for fine-grained query specialization.\n", "\n", - "### Requirements\n", - "1. \n", + "Your task is to **implement GQA from scratch** and validate it against PyTorchโ€™s `MultiheadAttention` under the special case where GQA behaves identically to MHA (i.e., when `num_query_heads == num_query_groups`).\n", "\n", - "### Constraints\n", - "- \n", + "---\n", "\n", + "### โœ… Requirements\n", + "\n", + "1. **Define the GQA Mechanism**\n", + " - Create a function `grouped_query_attention(q, k, v, num_query_groups, d_model, mask=None)`.\n", + " - Project `q`, `k`, and `v` using linear layers:\n", + " - Q projection โ†’ all query heads.\n", + " - K/V projection โ†’ shared across grouped key/value heads.\n", + " - Use `repeat_interleave()` to expand grouped K/V heads to match the number of Q heads.\n", + "\n", + "2. **Compute Attention**\n", + " - Apply scaled dot-product attention using `Q @ Kแต€ / sqrt(d_head)`.\n", + " - Support optional masking.\n", + " - Return output by concatenating heads and applying the output projection.\n", + "\n", + "3. **Validate Against MHA**\n", + " - Test your implementation using synthetic tensors.\n", + " - Compare your output to `torch.nn.MultiheadAttention` where GQA degenerates to MHA (`num_query_heads == num_query_groups`).\n", + " - Assert that both outputs match numerically.\n", + "\n", + "---\n", + "\n", + "### ๐Ÿ“ Constraints\n", + "\n", + "- โœ… Use only PyTorch (no external libraries like xformers or HuggingFace).\n", + "- โœ… Output shape must be `(batch_size, seq_len, d_model)`.\n", + "- โœ… Support optional attention masking.\n", + "- โœ… Validate output against `torch.nn.MultiheadAttention` for correctness.\n", + "\n", + "---\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", - "
\n" + "\n", + " - Use `nn.Linear(d_model, d_model)` for projecting `q`, `k`, and `v`.\n", + " - When `num_query_heads > num_query_groups`, use `.repeat_interleave()` to duplicate each groupโ€™s `K`/`V` to match query head count.\n", + " - Final output: reshape the multi-head outputs to `(batch_size, seq_len, d_model)` and apply the output projection layer.\n", + " - Test with `num_query_heads == num_query_groups` to confirm it behaves like MHA.\n", + "\n", + "\n", + "\n", + "---" ] }, { From 77b49931470f7c2981ff926cdcc3ea97d2bd312a Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:11:26 -0400 Subject: [PATCH 16/40] Update multi-head-attention-q5.ipynb --- llm/multi-head-attention-q5.ipynb | 43 ++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/llm/multi-head-attention-q5.ipynb b/llm/multi-head-attention-q5.ipynb index 4d01130..4262d7a 100644 --- a/llm/multi-head-attention-q5.ipynb +++ b/llm/multi-head-attention-q5.ipynb @@ -6,19 +6,54 @@ "source": [ "# Implement Attention from Scratch\n", "### Problem Statement\n", + "Multi-Head Attention (MHA) is the bread-and-butter of the Transformer architecture. It enables the model to **jointly attend** to information from different representation subspaces at different positions.\n", "\n", + "Your goal is to implement MHA from scratch using PyTorch, simulating exactly what `torch.nn.MultiheadAttention` does โ€” projecting Q, K, V for each head, computing attention weights, applying them to V, and concatenating the outputs across all heads.\n", + "\n", + "---\n", "\n", "### Requirements\n", - "1. \n", + "\n", + "1. **Linear Projections for Q, K, V**\n", + " - Project input `q`, `k`, `v` into a total of `d_model` dimensions.\n", + " - Split them into `num_heads` of `d_head = d_model // num_heads` each.\n", + "\n", + "2. **Scaled Dot-Product Attention per Head**\n", + " - Compute attention scores: \n", + " `scores = Q @ Kแต€ / sqrt(d_head)`\n", + " - Apply an optional `mask` before softmax.\n", + " - Use the scores to weight `V`.\n", + "\n", + "3. **Combine the Heads**\n", + " - Concatenate the outputs of all heads.\n", + " - Apply a final linear projection to restore the shape: `(batch_size, seq_len, d_model)`.\n", + "\n", + "4. **Validate Against PyTorchโ€™s Reference**\n", + " - Test your output against `torch.nn.MultiheadAttention` using the same input tensors.\n", + " - Check for numerical closeness using `torch.allclose()`.\n", + "\n", + "---\n", "\n", "### Constraints\n", - "- \n", "\n", + "- โœ… Use only PyTorch operations.\n", + "- โœ… Make sure all tensors are reshaped properly when splitting and combining heads.\n", + "- โœ… Support optional masking.\n", + "- โœ… Must match `torch.nn.MultiheadAttention` output when heads and shape are aligned.\n", + "\n", + "---\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Some details: \n", - "
\n" + "\n", + " - Use `.view()` and `.transpose()` to shape Q, K, V to `(batch_size, num_heads, seq_len, d_head)`.\n", + " - Softmax should be applied over the **last dimension** (attention scores across sequence).\n", + " - Use `.contiguous().view()` to flatten the multi-head outputs back into `(batch_size, seq_len, d_model)`.\n", + " - Match PyTorchโ€™s behavior using the same projections and batch-first format.\n", + "\n", + "\n", + "\n", + "---" ] }, { From ff5b96d6f99ccdc7d94e86efe873875065107754 Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Thu, 22 May 2025 23:13:22 -0400 Subject: [PATCH 17/40] Update attention-q4.ipynb --- llm/attention-q4.ipynb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llm/attention-q4.ipynb b/llm/attention-q4.ipynb index 2a18a68..11cbe2a 100644 --- a/llm/attention-q4.ipynb +++ b/llm/attention-q4.ipynb @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -82,7 +82,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -120,14 +120,13 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "torch.Size([1, 3, 3])\n", "tensor([[[ 6.9352, 6.2411, 8.8509],\n", " [ 6.1200, 8.0314, 9.2154],\n", " [ 6.9659, 4.0257, 12.7036]]])\n", @@ -164,7 +163,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.9" + "version": "3.9.6" } }, "nbformat": 4, From f7ccb8c2d0e1fa785455ec89f792cf8b607ac936 Mon Sep 17 00:00:00 2001 From: AtulAravindDas <161445393+AtulAravindDas@users.noreply.github.com> Date: Fri, 23 May 2025 16:32:19 -0400 Subject: [PATCH 18/40] Update README.md Signed-off-by: AtulAravindDas <161445393+AtulAravindDas@users.noreply.github.com> --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e7abc18..e94d0dc 100644 --- a/README.md +++ b/README.md @@ -70,15 +70,15 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 1. Implement KL Divergence Loss 2. Implement RMS Norm -3. Implement Byte Pair Encoding from Scratch -4. Create an embeddings out of an LLM +3. [Implement Byte Pair Encoding from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/BPE-q3.ipynb) +4. [Create an embeddings out of an LLM](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/embeddings-q2.ipynb) 5. Implement Predictive Prefill with Speculative Decoding -6. Implement Attention from Scratch -7. Implement Multi-Head Attention from Scratch -8. Implement Grouped Query Attention from Scratch +6. [Implement Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/attention-q4.ipynb) +7. [Implement Multi-Head Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/multi-head-attention-q5.ipynb) +8. [Implement Grouped Query Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/grouped-query-attention.ipynb) 9. Implement KV Cache in Multi-Head Attention from Scratch -10. Implement Sinusoidal Embeddings -11. Implement ROPE Embeddings +10. [Implement Sinusoidal Embeddings](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/sinusoidal-q7.ipynb) +11. [Implement ROPE Embeddings](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/rope-q8.ipynb) 12. Implement SmolLM from Scratch 13. Implement Quantization of Models a. Types of Quantization From 52fc43811c3a11d4af233fc24110eaecdf40af3e Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Fri, 23 May 2025 20:17:01 -0400 Subject: [PATCH 19/40] Added files into required folders, updated the README.md, created questions --- README.md | 56 +++---- llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb | 122 ++++++++++++++ llm/{ => Byte-Pair-Encoder}/BPE-q3.ipynb | 0 .../embeddings-q2-Question.ipynb | 126 ++++++++++++++ .../embeddings-q2.ipynb | 0 .../grouped-query-attention-Question.ipynb | 150 +++++++++++++++++ .../grouped-query-attention.ipynb | 0 .../attention-q4-Question.ipynb | 121 ++++++++++++++ .../attention-q4.ipynb | 0 .../multi-head-attention-q5-Question.ipynb | 149 +++++++++++++++++ .../multi-head-attention-q5.ipynb | 0 .../rope-q8-Question.ipynb | 146 +++++++++++++++++ .../rope-q8.ipynb | 0 .../sinusoidal-q7-Question.ipynb | 155 ++++++++++++++++++ .../sinusoidal-q7.ipynb | 0 llm/SmolLM/smollm-q12-Question.ipynb | 63 +++++++ llm/{ => SmolLM}/smollm-q12.ipynb | 8 + 17 files changed, 1068 insertions(+), 28 deletions(-) create mode 100644 llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb rename llm/{ => Byte-Pair-Encoder}/BPE-q3.ipynb (100%) create mode 100644 llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb rename llm/{ => Create-Embeddings-out-of-an-LLM}/embeddings-q2.ipynb (100%) create mode 100644 llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb rename llm/{ => Grouped-Query-Attention}/grouped-query-attention.ipynb (100%) create mode 100644 llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb rename llm/{ => Implement-Attention-from-Scratch}/attention-q4.ipynb (100%) create mode 100644 llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb rename llm/{ => Multi-Head-Attention}/multi-head-attention-q5.ipynb (100%) create mode 100644 llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb rename llm/{ => Rotary-Positional-Embedding}/rope-q8.ipynb (100%) create mode 100644 llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb rename llm/{ => Sinusoidal-Positional-Embedding}/sinusoidal-q7.ipynb (100%) create mode 100644 llm/SmolLM/smollm-q12-Question.ipynb rename llm/{ => SmolLM}/smollm-q12.ipynb (99%) diff --git a/README.md b/README.md index e7abc18..0e39494 100644 --- a/README.md +++ b/README.md @@ -32,36 +32,36 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st ## Question Set ### ๐ŸŸขEasy -1. [Implement linear regression](https://github.com/Exorust/TorchLeet/blob/main/e1/lin-regression.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e1/lin-regression_SOLN.ipynb) -2. [Write a custom Dataset and Dataloader to load from a CSV file](https://github.com/Exorust/TorchLeet/blob/main/e2/custom-dataset.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e2/custom-dataset_SOLN.ipynb) -3. [Write a custom activation function (Simple)](https://github.com/Exorust/TorchLeet/blob/main/e3/custom-activation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e3/custom-activation_SOLN.ipynb) -4. [Implement Custom Loss Function (Huber Loss)](https://github.com/Exorust/TorchLeet/blob/main/e4/custom-loss.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e4/custom-loss_SOLN.ipynb) -5. [Implement a Deep Neural Network](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e5/custon-DNN_SOLN.ipynb) -6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e6/tensorboard_SOLN.ipynb) -7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e7/save_model_SOLN.ipynb) +1. [Implement linear regression](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression_SOLN.ipynb) +2. [Write a custom Dataset and Dataloader to load from a CSV file](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset_SOLN.ipynb) +3. [Write a custom activation function (Simple)](https://github.com/Exorust/TorchLeet/torch/easy/e3/custom-activation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e3/custom-activation_SOLN.ipynb) +4. [Implement Custom Loss Function (Huber Loss)](https://github.com/Exorust/TorchLeet/torch/easy/main/e4/custom-loss.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/main/e4/custom-loss_SOLN.ipynb) +5. [Implement a Deep Neural Network](https://github.com/Exorust/TorchLeet/torch/easy/e5/custon-DNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e5/custon-DNN_SOLN.ipynb) +6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard_SOLN.ipynb) +7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model_SOLN.ipynb) 10. Implement Softmax function from scratch ### ๐ŸŸกMedium -1. [Implement an LSTM](https://github.com/Exorust/TorchLeet/blob/main/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m1/LSTM_SOLN.ipynb) -2. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/blob/main/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m2/CNN_SOLN.ipynb) +1. [Implement an LSTM](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) +2. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) 3. [Implement parameter initialization for a CNN]() [(Solution)]() -4. [Implement an RNN](https://github.com/Exorust/TorchLeet/blob/main/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m3/RNN_SOLN.ipynb) -5. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/blob/main/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m4/augmentation_SOLN.ipynb) -6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/blob/main/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m5/bench_SOLN.ipynb) -7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/blob/main/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/m6/autoencoder_SOLN.ipynb) +4. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) +5. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) +6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) +7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) ### ๐Ÿ”ดHard -1. [Write a custom Autograd function for activation (SILU)](https://github.com/Exorust/TorchLeet/blob/main/h1/custom-autgrad-function.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h1/custom-autgrad-function_SOLN.ipynb) +1. [Write a custom Autograd function for activation (SILU)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function_SOLN.ipynb) 2. Write a Neural Style Transfer -3. [Write a Transformer](https://github.com/Exorust/TorchLeet/blob/main/h3/transformer.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h3/transformer_SOLN.ipynb) -4. [Write a GAN](https://github.com/Exorust/TorchLeet/blob/main/h4/GAN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h4/GAN_SOLN.ipynb) -5. [Write Sequence-to-Sequence with Attention](https://github.com/Exorust/TorchLeet/blob/main/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h5/seq-to-seq-with-Attention_SOLN.ipynb) -6. [Quantize your language model](https://github.com/Exorust/TorchLeet/blob/main/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h6/quantize-language-model_SOLN.ipynb) +3. [Write a Transformer](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer_SOLN.ipynb) +4. [Write a GAN](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN_SOLN.ipynb) +5. [Write Sequence-to-Sequence with Attention](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb) +6. [Quantize your language model](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model_SOLN.ipynb) 7. [Enable distributed training in pytorch (DistributedDataParallel)] 8. [Work with Sparse Tensors] -9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/blob/main/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h9/cuda-amp_SOLN.ipynb) -10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/blob/main/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/h10/xai_SOLN.ipynb) +9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) +10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai_SOLN.ipynb) ## LLM Set @@ -70,16 +70,16 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 1. Implement KL Divergence Loss 2. Implement RMS Norm -3. Implement Byte Pair Encoding from Scratch -4. Create an embeddings out of an LLM +3. [Implement Byte Pair Encoding from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3.ipynb) +4. [Create an embeddings out of an LLM](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) 5. Implement Predictive Prefill with Speculative Decoding -6. Implement Attention from Scratch -7. Implement Multi-Head Attention from Scratch -8. Implement Grouped Query Attention from Scratch +6. [Implement Attention from Scratch ](https://github.com/Exorust/TorchLeet/torch/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Implement-Attention-from-Scratch/attention-q4.ipynb) +7. [Implement Multi-Head Attention from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Multi-Head-Attention/multi-head-attention-q5.ipynb) +8. [Implement Grouped Query Attention from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Grouped-Query-Attention/grouped-query-attention.ipynb) 9. Implement KV Cache in Multi-Head Attention from Scratch -10. Implement Sinusoidal Embeddings -11. Implement ROPE Embeddings -12. Implement SmolLM from Scratch +10. [Implement Sinusoidal Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) +11. [Implement ROPE Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8.ipynb) +12. [Implement SmolLM from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12.ipynb) 13. Implement Quantization of Models a. Types of Quantization 14. Implement Beam Search atop LLM for decoding diff --git a/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb b/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb new file mode 100644 index 0000000..6861832 --- /dev/null +++ b/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb @@ -0,0 +1,122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Write a Byte Pain Encoder in Python\n", + "\n", + "### Problem Statement\n", + "Implement a **Transformer model** in PyTorch by completing the required sections. The model should consist of an embedding layer, a Transformer encoder, and an output layer for sequence processing and prediction.\n", + "\n", + "### Requirements\n", + "1. **Define the Transformer Model Architecture**:\n", + " - **Embedding Layer**:\n", + " - Implement a layer to transform input data into a higher-dimensional space.\n", + " - Use a `torch.nn.Linear` or `torch.nn.Embedding` layer to create embeddings from the input.\n", + " - **Transformer Encoder**:\n", + " - Use `torch.nn.TransformerEncoder` or `torch.nn.Transformer` to process sequences with attention.\n", + " - Configure parameters such as the number of attention heads and encoder layers.\n", + " - **Output Layer**:\n", + " - Add a fully connected (linear) layer to reduce the transformer's sequence output into the desired output dimension.\n", + "\n", + "2. **Implement the Forward Method**:\n", + " - Map the input to the higher-dimensional space using the embedding layer.\n", + " - Pass the transformed input through the Transformer encoder.\n", + " - Use the output layer to convert the encoded sequence into predictions.\n", + "\n", + "### Constraints\n", + "- Handle input padding correctly for variable-length sequences.\n", + "- Ensure compatibility with batch processing by correctly shaping input and output tensors.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict, Counter\n", + "\n", + "def get_vocab(corpus):\n", + " \"\"\"Creates a vocabulary with words split into characters and a special end-of-word token.\"\"\"\n", + " \n", + " return vocab\n", + "\n", + "def get_stats(vocab):\n", + " \"\"\"Counts frequency of adjacent symbol pairs.\"\"\"\n", + " \n", + " return pairs\n", + "\n", + "def merge_vocab(pair, vocab):\n", + " \"\"\"Merges the most frequent pair into a single symbol.\"\"\"\n", + " \n", + " return new_vocab\n", + "\n", + "def byte_pair_encoding(corpus, num_merges=10):\n", + " \"\"\"Performs BPE on a corpus.\"\"\"\n", + " \n", + " return vocab, merges\n", + "\n", + "# Example usage\n", + "corpus = [\"low\", \"lowest\", \"newer\", \"wider\"]\n", + "final_vocab, merge_operations = byte_pair_encoding(corpus, num_merges=10)\n", + "\n", + "print(\"\\nFinal Vocabulary:\")\n", + "for word in final_vocab:\n", + " print(' '.join(word), \":\", final_vocab[word])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def test_get_vocab():\n", + " corpus = [\"test\"]\n", + " vocab = get_vocab(corpus)\n", + " assert vocab == {('t', 'e', 's', 't', ''): 1}\n", + " print(\"โœ“ test_get_vocab passed\")\n", + "\n", + "def test_get_stats():\n", + " vocab = {('t', 'e', 's', 't', ''): 1}\n", + " stats = get_stats(vocab)\n", + " expected = {\n", + " ('t', 'e'): 1,\n", + " ('e', 's'): 1,\n", + " ('s', 't'): 1,\n", + " ('t', ''): 1\n", + " }\n", + " assert stats == expected\n", + " print(\"โœ“ test_get_stats passed\")\n", + "\n", + "def test_merge_vocab():\n", + " vocab = {('t', 'e', 's', 't', ''): 1}\n", + " merged = merge_vocab(('e', 's'), vocab)\n", + " expected = {('t', 'es', 't', ''): 1}\n", + " assert merged == expected\n", + " print(\"โœ“ test_merge_vocab passed\")\n", + "\n", + "def test_bpe_sequence():\n", + " corpus = [\"low\", \"lower\", \"newest\", \"widest\"]\n", + " final_vocab, merges = byte_pair_encoding(corpus, num_merges=5)\n", + " assert isinstance(final_vocab, dict)\n", + " assert all(isinstance(pair, tuple) for pair in merges)\n", + " assert len(merges) == 5\n", + " print(\"โœ“ test_bpe_sequence passed\")\n", + "\n", + "# Run all tests\n", + "test_get_vocab()\n", + "test_get_\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/BPE-q3.ipynb b/llm/Byte-Pair-Encoder/BPE-q3.ipynb similarity index 100% rename from llm/BPE-q3.ipynb rename to llm/Byte-Pair-Encoder/BPE-q3.ipynb diff --git a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb new file mode 100644 index 0000000..55d6507 --- /dev/null +++ b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb @@ -0,0 +1,126 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create Embeddings out of an LLM\n", + "\n", + "### Problem Statement\n", + "Your mission, should you choose to accept it, is to extract **meaningful sentence-level embeddings** using a pre-trained **causal language model (SmolLM2-135M)** on Amazon Reviews.\n", + "\n", + "You're working with a **generative language model**, but youโ€™re not here to generate Shakespeare. Instead, youโ€™ll tap into its **hidden states** to get semantic embeddings that capture the essence of a review โ€” the good, the bad, and the brutally honest.\n", + "\n", + "---\n", + "\n", + "### Requirements\n", + "\n", + "1. **Load and Tokenize Text**\n", + " - Use the `McAuley-Lab/Amazon-Reviews-2023` dataset (subset: `raw_review_All_Beauty`).\n", + " - Load ~10 sample reviews for testing.\n", + " - Tokenize them using `\"HuggingFaceTB/SmolLM2-135M\"` tokenizer.\n", + "\n", + "2. **Extract Embeddings**\n", + " - Run the tokenized batch through the model with `output_hidden_states=True`.\n", + " - Access the **last hidden layer** from `outputs.hidden_states[-1]`.\n", + "\n", + "3. **Compute Sentence Embeddings**\n", + " - Options:\n", + " - If the model uses a classification token (e.g., `[CLS]`), extract its embedding.\n", + " - For causal models (which typically donโ€™t), **average the token embeddings** from the final layer, **excluding padding tokens**.\n", + "\n", + "4. **Display the Result**\n", + " - Show the shape of your final sentence embedding tensor.\n", + " - Print at least one sentence-level embedding to verify everything worked.\n", + "\n", + "---\n", + "\n", + "### Constraints\n", + "\n", + "- โŒ Do **not** use sentence-transformers or pre-built embedding tools like `bert-as-service`.\n", + "- โŒ Do **not** generate text (no `.generate()`).\n", + "- โœ… Use only Hugging Face's `AutoModelForCausalLM` and `AutoTokenizer`.\n", + "- โœ… Exclude padding tokens when computing average embeddings.\n", + "- โœ… Ensure everything runs on `cuda` if available.\n", + "\n", + "---\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + "\n", + "```python\n", + "# Run model with hidden states\n", + "outputs = model(**tokenized_inputs, output_hidden_states=True, return_dict=True)\n", + "\n", + "# Get the last hidden layer (batch_size, seq_len, hidden_dim)\n", + "last_hidden = outputs.hidden_states[-1]\n", + "\n", + "# Use the attention mask to avoid averaging over padding\n", + "attention_mask = tokenized_inputs['attention_mask'] # (batch_size, seq_len)\n", + "\n", + "# Compute masked average: zero out padding tokens\n", + "masked_embeddings = last_hidden * attention_mask.unsqueeze(-1) # broadcast mask\n", + "summed = masked_embeddings.sum(dim=1) # sum across tokens\n", + "count = attention_mask.sum(dim=1, keepdim=True) # count of non-padding tokens\n", + "\n", + "# Final sentence-level embeddings\n", + "sentence_embeddings = summed / count # (batch_size, hidden_dim)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load Amazon Reviews dataset\n", + "from datasets import load_dataset\n", + "dataset = load_dataset(\"McAuley-Lab/Amazon-Reviews-2023\", \"raw_review_All_Beauty\", trust_remote_code=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Load SmolLM2-135M model and tokenizer\n", + "from transformers import AutoTokenizer, AutoModelForCausalLM\n", + "\n", + "# Load model and tokenizer\n", + "tokenizer = AutoTokenizer.from_pretrained(\"HuggingFaceTB/SmolLM2-135M\")\n", + "\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "model.to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/embeddings-q2.ipynb b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb similarity index 100% rename from llm/embeddings-q2.ipynb rename to llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb diff --git a/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb b/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb new file mode 100644 index 0000000..502e3b3 --- /dev/null +++ b/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb @@ -0,0 +1,150 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### ๐Ÿง  Problem Statement\n", + "Standard Multi-Head Attention (MHA) assigns a separate query, key, and value projection to each attention head. But thatโ€™s not always the most efficient approach. \n", + "\n", + "Enter **Grouped Query Attention (GQA)** โ€” a clever mechanism where you use more query heads than key-value heads. This reduces compute/memory costs while still allowing for fine-grained query specialization.\n", + "\n", + "Your task is to **implement GQA from scratch** and validate it against PyTorchโ€™s `MultiheadAttention` under the special case where GQA behaves identically to MHA (i.e., when `num_query_heads == num_query_groups`).\n", + "\n", + "---\n", + "\n", + "### โœ… Requirements\n", + "\n", + "1. **Define the GQA Mechanism**\n", + " - Create a function `grouped_query_attention(q, k, v, num_query_groups, d_model, mask=None)`.\n", + " - Project `q`, `k`, and `v` using linear layers:\n", + " - Q projection โ†’ all query heads.\n", + " - K/V projection โ†’ shared across grouped key/value heads.\n", + " - Use `repeat_interleave()` to expand grouped K/V heads to match the number of Q heads.\n", + "\n", + "2. **Compute Attention**\n", + " - Apply scaled dot-product attention using `Q @ Kแต€ / sqrt(d_head)`.\n", + " - Support optional masking.\n", + " - Return output by concatenating heads and applying the output projection.\n", + "\n", + "3. **Validate Against MHA**\n", + " - Test your implementation using synthetic tensors.\n", + " - Compare your output to `torch.nn.MultiheadAttention` where GQA degenerates to MHA (`num_query_heads == num_query_groups`).\n", + " - Assert that both outputs match numerically.\n", + "\n", + "---\n", + "\n", + "### ๐Ÿ“ Constraints\n", + "\n", + "- โœ… Use only PyTorch (no external libraries like xformers or HuggingFace).\n", + "- โœ… Output shape must be `(batch_size, seq_len, d_model)`.\n", + "- โœ… Support optional attention masking.\n", + "- โœ… Validate output against `torch.nn.MultiheadAttention` for correctness.\n", + "\n", + "---\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + "\n", + " - Use `nn.Linear(d_model, d_model)` for projecting `q`, `k`, and `v`.\n", + " - When `num_query_heads > num_query_groups`, use `.repeat_interleave()` to duplicate each groupโ€™s `K`/`V` to match query head count.\n", + " - Final output: reshape the multi-head outputs to `(batch_size, seq_len, d_model)` and apply the output projection layer.\n", + " - Test with `num_query_heads == num_query_groups` to confirm it behaves like MHA.\n", + "\n", + "
\n", + "\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "def grouped_query_attention(q, k, v, num_query_groups, d_model, mask=None):\n", + " \"\"\"\n", + " Implements Grouped Query Attention (GQA).\n", + "\n", + " Args:\n", + " q (Tensor): Query tensor of shape (batch_size, seq_len, d_model)\n", + " k (Tensor): Key tensor of shape (batch_size, seq_len, d_model)\n", + " v (Tensor): Value tensor of shape (batch_size, seq_len, d_model)\n", + " num_query_groups (int): Number of key/value groups (fewer than query groups)\n", + " d_model (int): Total embedding dimension\n", + " mask (Tensor, optional): Masking tensor for attention\n", + "\n", + " Returns:\n", + " Tensor: GQA output of shape (batch_size, seq_len, d_model)\n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Temporarily set\n", + "num_query_heads = 8\n", + "num_query_groups = 8 # => GQA behaves like MHA\n", + "\n", + "# Use same d_model and input\n", + "multihead_attn = torch.nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, bias=False, batch_first=True)\n", + "output_ref, _ = multihead_attn(q, k, v)\n", + "output_custom = grouped_query_attention(q, k, v, num_query_groups=num_query_groups, d_model=d_model)\n", + "\n", + "# Compare\n", + "assert torch.allclose(output_custom, output_ref, atol=1e-8, rtol=1e-5)\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/grouped-query-attention.ipynb b/llm/Grouped-Query-Attention/grouped-query-attention.ipynb similarity index 100% rename from llm/grouped-query-attention.ipynb rename to llm/Grouped-Query-Attention/grouped-query-attention.ipynb diff --git a/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb new file mode 100644 index 0000000..a7826c2 --- /dev/null +++ b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "Implement a **Scaled Dot-Product Attention** mechanism from scratch using PyTorch. Your mission (should you choose to accept it) is to replicate what PyTorch's built-in `scaled_dot_product_attention` does โ€” manually. This core component is essential in Transformer architectures and helps models focus on relevant parts of a sequence. You'll test your implementation against PyTorch's native one to ensure you nailed it.\n", + "\n", + "\n", + "### Requirements\n", + "1. **Define the Function**:\n", + " - Create a function `scaled_dot_product_attention(q, k, v, mask=None)` that:\n", + " - Computes attention scores via the dot product of query and key vectors.\n", + " - Scales the scores using the square root of the key dimension.\n", + " - Applies an optional mask to the scores.\n", + " - Applies softmax to convert scores into attention weights.\n", + " - Uses these weights to compute a weighted sum of values (V).\n", + "\n", + "2. **Test Your Work**:\n", + " - Use sample tensors for query (Q), key (K), and value (V).\n", + " - Compare the result of your custom implementation with PyTorch's `F.scaled_dot_product_attention` using an `assert` to check numerical accuracy.\n", + "\n", + "\n", + "### Constraints\n", + "- โŒ Do NOT use `F.scaled_dot_product_attention` inside your custom function โ€” that defeats the whole point.\n", + "- โœ… Your implementation must handle **batch dimensions** correctly.\n", + "- โœ… Support optional **masking** for future tokens or padding.\n", + "- โœ… Use only PyTorch ops โ€” no cheating with external attention libs.\n", + "\n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Use `torch.matmul()` to compute dot products and `F.softmax()` for the final attention weights. The mask (if used) should be applied **before** the softmax using `masked_fill`.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "q = torch.tensor([[[1.0, 0.5, 0.2], # Query for token 1\n", + " [0.3, 1.2, 0.7], # Query for token 2\n", + " [0.8, 0.1, 1.5]]]) # Query for token 3\n", + "\n", + "k = torch.tensor([[[1.0, 0.2, 0.3], # Key for token 1\n", + " [0.4, 1.5, 0.6], # Key for token 2\n", + " [0.7, 0.1, 1.8]]]) # Key for token 3\n", + "\n", + "v = torch.tensor([[[10.0, 2.0, 3.0], # Value for token 1\n", + " [4.0, 15.0, 6.0], # Value for token 2\n", + " [7.0, 1.0, 18.0]]]) # Value for token 3\n", + "\n", + "print(q.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def scaled_dot_product_attention(q, k, v, mask=None):\n", + " \"\"\"\n", + " Compute the scaled dot-product attention.\n", + " \n", + " Args:\n", + " q: Query tensor of shape (..., seq_len_q, d_k)\n", + " k: Key tensor of shape (..., seq_len_k, d_k)\n", + " v: Value tensor of shape (..., seq_len_k, d_v)\n", + " mask: Optional mask tensor of shape (..., seq_len_q, seq_len_k)\n", + " \n", + " Returns:\n", + " output: Attention output tensor of shape (..., seq_len_q, d_v)\n", + " attention_weights: Attention weights tensor of shape (..., seq_len_q, seq_len_k)\n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Testing on data & compare\n", + "output_custom, _ = scaled_dot_product_attention(q, k, v)\n", + "print(output_custom)\n", + "output = F.scaled_dot_product_attention(q, k, v)\n", + "print(output)\n", + "\n", + "assert torch.allclose(output_custom, output, atol=1e-08, rtol=1e-05) # Check if they are close enough.\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/attention-q4.ipynb b/llm/Implement-Attention-from-Scratch/attention-q4.ipynb similarity index 100% rename from llm/attention-q4.ipynb rename to llm/Implement-Attention-from-Scratch/attention-q4.ipynb diff --git a/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb b/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb new file mode 100644 index 0000000..01c7f9a --- /dev/null +++ b/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb @@ -0,0 +1,149 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "Multi-Head Attention (MHA) is the bread-and-butter of the Transformer architecture. It enables the model to **jointly attend** to information from different representation subspaces at different positions.\n", + "\n", + "Your goal is to implement MHA from scratch using PyTorch, simulating exactly what `torch.nn.MultiheadAttention` does โ€” projecting Q, K, V for each head, computing attention weights, applying them to V, and concatenating the outputs across all heads.\n", + "\n", + "---\n", + "\n", + "### Requirements\n", + "\n", + "1. **Linear Projections for Q, K, V**\n", + " - Project input `q`, `k`, `v` into a total of `d_model` dimensions.\n", + " - Split them into `num_heads` of `d_head = d_model // num_heads` each.\n", + "\n", + "2. **Scaled Dot-Product Attention per Head**\n", + " - Compute attention scores: \n", + " `scores = Q @ Kแต€ / sqrt(d_head)`\n", + " - Apply an optional `mask` before softmax.\n", + " - Use the scores to weight `V`.\n", + "\n", + "3. **Combine the Heads**\n", + " - Concatenate the outputs of all heads.\n", + " - Apply a final linear projection to restore the shape: `(batch_size, seq_len, d_model)`.\n", + "\n", + "4. **Validate Against PyTorchโ€™s Reference**\n", + " - Test your output against `torch.nn.MultiheadAttention` using the same input tensors.\n", + " - Check for numerical closeness using `torch.allclose()`.\n", + "\n", + "---\n", + "\n", + "### Constraints\n", + "\n", + "- โœ… Use only PyTorch operations.\n", + "- โœ… Make sure all tensors are reshaped properly when splitting and combining heads.\n", + "- โœ… Support optional masking.\n", + "- โœ… Must match `torch.nn.MultiheadAttention` output when heads and shape are aligned.\n", + "\n", + "---\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + "\n", + " - Use `.view()` and `.transpose()` to shape Q, K, V to `(batch_size, num_heads, seq_len, d_head)`.\n", + " - Softmax should be applied over the **last dimension** (attention scores across sequence).\n", + " - Use `.contiguous().view()` to flatten the multi-head outputs back into `(batch_size, seq_len, d_model)`.\n", + " - Match PyTorchโ€™s behavior using the same projections and batch-first format.\n", + "\n", + "
\n", + "\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "\n", + "\n", + "\n", + "\n", + "def multi_head_attention(q, k, v, num_heads, d_model, mask=None):\n", + " \"\"\"\n", + " Implements multi-head attention.\n", + " \n", + " Args:\n", + " q (Tensor): Query tensor of shape (batch_size, seq_len, d_model)\n", + " k (Tensor): Key tensor of shape (batch_size, seq_len, d_model)\n", + " v (Tensor): Value tensor of shape (batch_size, seq_len, d_model)\n", + " num_heads (int): Number of attention heads\n", + " d_model (int): Total embedding dimension\n", + " mask (Tensor, optional): Masking tensor for attention\n", + " \n", + " Returns:\n", + " Tensor: Multi-head attention output of shape (batch_size, seq_len, d_model)\n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Testing on data & compare\n", + "output_custom = multi_head_attention(q, k, v, num_heads, d_model)\n", + "print(output_custom)\n", + "\n", + "multihead_attn = torch.nn.MultiheadAttention(embed_dim=d_model, num_heads=num_heads, bias=False, batch_first=True)\n", + "output, _ = multihead_attn(q, k, v)\n", + "print(output)\n", + "\n", + "assert torch.allclose(output_custom, output, atol=1e-08, rtol=1e-05) # Check if they are close enough.\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/multi-head-attention-q5.ipynb b/llm/Multi-Head-Attention/multi-head-attention-q5.ipynb similarity index 100% rename from llm/multi-head-attention-q5.ipynb rename to llm/Multi-Head-Attention/multi-head-attention-q5.ipynb diff --git a/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb b/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb new file mode 100644 index 0000000..2462bb4 --- /dev/null +++ b/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb @@ -0,0 +1,146 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement ROPE from Scratch\n", + "# ๐Ÿ” Rotary Positional Embeddings in PyTorch\n", + "\n", + "### ๐Ÿง  Problem Statement\n", + "Transformers need a sense of **order**, but vanilla attention mechanisms are position-agnostic. Positional encodings help inject this order-awareness into the model. \n", + "\n", + "Your mission is to implement **Rotary Positional Embeddings (RoPE)** from scratch โ€” a newer and slicker technique that rotates the query and key vectors instead of simply adding sine-cosine vectors. This method preserves attention efficiency while enabling better generalization for long sequences.\n", + "\n", + "---\n", + "\n", + "### โœ… Requirements\n", + "\n", + "1. **Implement the Rotary Module**\n", + " - Construct a `Rotary` class to compute sinusoidal frequencies.\n", + " - Precompute and cache `cos` and `sin` values per sequence length.\n", + " - Register these as buffers to keep them on the correct device.\n", + "\n", + "2. **Define Rotation Helpers**\n", + " - `rotate_half(x)` splits and rotates half the dimensions of a tensor.\n", + " - `apply_rotary_pos_emb(q, k, cos, sin)` applies these rotations to Q and K.\n", + "\n", + "3. **Simulate Usage**\n", + " - Create synthetic tensors for Q, K, V.\n", + " - Generate rotary embeddings using the custom `Rotary` module.\n", + " - Apply rotary embeddings to Q and K.\n", + "\n", + "4. **Verify Dimensions**\n", + " - Final shapes should align with expected shapes for attention modules.\n", + " - Confirm RoPE is applied before dot-product attention would normally occur.\n", + "\n", + "---\n", + "\n", + "### ๐Ÿ“ Constraints\n", + "\n", + "- โœ… Use only PyTorch โ€” no Fairseq or HuggingFace positional modules.\n", + "- โœ… Must support dynamic sequence lengths and cache embeddings per sequence.\n", + "- โœ… Should handle odd/even dimensional splits correctly.\n", + "- โŒ Do **not** manually plug in Fairseqโ€™s `SinusoidalPositionalEmbedding`.\n", + "\n", + "---\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " - Use `torch.einsum(\"i,j->ij\", t, inv_freq)` to compute frequency pairs.\n", + " - Cache the cosine and sine values in the `Rotary` class using `self.register_buffer()`.\n", + " - The `rotate_half(x)` function should split `x` into two halves and rotate them: `[-x2, x1]`.\n", + " - Apply the rotary transformation using: \n", + " `(q * cos) + (rotate_half(q) * sin)` \n", + " and similarly for `k`.\n", + " - Remember to broadcast `cos` and `sin` to match the shape of `q` and `k`.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Rotary(torch.nn.Module):\n", + " \n", + "def rotate_half(x):\n", + " \n", + "\n", + "\n", + "@torch.jit.script\n", + "def apply_rotary_pos_emb(q, k, cos, sin):\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from fairseq.modules.sinusoidal_positional_embedding import SinusoidalPositionalEmbedding\n", + "\n", + "max_seq_len = 100\n", + "d_model = 64\n", + "\n", + "# Fairseq's implementation requires the number of embeddings (seq length) and embedding dim\n", + "# pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len, padding_idx=None)\n", + "\n", + "# Generate embeddings for a sequence of length 50\n", + "seq_len = 50\n", + "positions = torch.arange(seq_len).unsqueeze(0) # Shape: (1, seq_len)\n", + "# positional_encoding = pos_emb(positions) # Shape: (1, seq_len, d_model)\n", + "\n", + "custom_pos_emb = Rotary(d_model, max_seq_len)\n", + "\n", + "positional_encoding_custom = apply_rotary_pos_emb(positions)\n", + "\n", + "print(positional_encoding_custom.shape) # (1, 50, 64)\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/rope-q8.ipynb b/llm/Rotary-Positional-Embedding/rope-q8.ipynb similarity index 100% rename from llm/rope-q8.ipynb rename to llm/Rotary-Positional-Embedding/rope-q8.ipynb diff --git a/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb b/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb new file mode 100644 index 0000000..93657f1 --- /dev/null +++ b/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb @@ -0,0 +1,155 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Implement Attention from Scratch\n", + "### Problem Statement\n", + "Transformers are order-agnostic โ€” they see tokens like goldfish: no sense of sequence. To inject **position awareness** into the model, we use **Sinusoidal Positional Embeddings**, where each position in the sequence gets a unique deterministic vector. These vectors are computed using sine and cosine waves at different frequencies.\n", + "\n", + "Your task is to implement the sinusoidal position encoding mechanism from scratch using PyTorch โ€” no cheating with built-ins from `fairseq` or Hugging Face.\n", + "\n", + "---\n", + "\n", + "### Requirements\n", + "\n", + "1. **Define the Sinusoidal Embedding Class**\n", + " - Implement a `SinusoidalPositionalEmbedding` class inheriting from `nn.Module`.\n", + " - Initialize with `max_seq_len` and `d_model`.\n", + " - Create a tensor `pe` of shape `(max_seq_len, d_model)` filled with sine and cosine encodings:\n", + " - `sin(position * ฯ‰)` for even indices\n", + " - `cos(position * ฯ‰)` for odd indices\n", + "\n", + "2. **Register as Buffer**\n", + " - Use `self.register_buffer(\"pe\", pe)` to store `pe` without treating it as a trainable parameter.\n", + "\n", + "3. **Generate Encodings**\n", + " - On calling `forward(x)`, return the slice of positional encodings matching the sequence length of `x`.\n", + "\n", + "4. **Test the Embeddings**\n", + " - Initialize the embedding class with `max_seq_len = 100` and `d_model = 64`.\n", + " - Pass a sequence of length 50 to verify the returned shape is `(1, 50, 64)`.\n", + "\n", + "---\n", + "\n", + "### Constraints\n", + "\n", + "- โœ… Do not use Hugging Face, Fairseq, or built-in PyTorch modules for position encoding.\n", + "- โœ… Ensure the `pe` tensor is not a trainable parameter.\n", + "- โœ… Support any sequence length up to `max_seq_len`.\n", + "- โŒ Do not inject these embeddings directly into token embeddings yet โ€” this is just the embedding module.\n", + "\n", + "---\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + "\n", + " - Use `torch.arange(0, max_seq_len).unsqueeze(1)` to create position indices.\n", + " - Compute frequencies with `torch.exp(torch.arange(0, d_model, 2) * -(math.log(10000.0) / d_model))`.\n", + " - Alternate `sin` and `cos` values for even and odd embedding dimensions.\n", + " - When returning the embedding in `forward`, use `.unsqueeze(0)` to broadcast over the batch dimension.\n", + "\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Synthetic data\n", + "torch.manual_seed(42)\n", + "batch_size = 3\n", + "seq_len = 4\n", + "d_model = 8\n", + "num_heads = 2\n", + "\n", + "q = torch.rand(batch_size, seq_len, d_model)\n", + "k = torch.rand(batch_size, seq_len, d_model)\n", + "v = torch.rand(batch_size, seq_len, d_model)\n", + "print(q.shape)\n", + "\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "device = \"cpu\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class SinusoidalPositionalEmbedding(nn.Module):\n", + " def __init__(self, max_seq_len: int, d_model: int):\n", + " \"\"\"\n", + " Initializes the sinusoidal positional embedding.\n", + " \n", + " Args:\n", + " max_seq_len (int): Maximum sequence length.\n", + " d_model (int): Embedding dimension.\n", + " \"\"\"\n", + " \n", + "\n", + " def forward(self, x):\n", + " \"\"\"\n", + " Returns the positional embedding for a given input tensor.\n", + " \n", + " Args:\n", + " x (Tensor): Input tensor of shape (batch_size, seq_len, d_model).\n", + " \n", + " Returns:\n", + " Tensor: Positional embeddings of shape (batch_size, seq_len, d_model).\n", + " \"\"\"\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from fairseq.modules.sinusoidal_positional_embedding import SinusoidalPositionalEmbedding\n", + "\n", + "max_seq_len = 100\n", + "d_model = 64\n", + "\n", + "# Fairseq's implementation requires the number of embeddings (seq length) and embedding dim\n", + "# pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len, padding_idx=None)\n", + "\n", + "# Generate embeddings for a sequence of length 50\n", + "seq_len = 50\n", + "positions = torch.arange(seq_len).unsqueeze(0) # Shape: (1, seq_len)\n", + "# positional_encoding = pos_emb(positions) # Shape: (1, seq_len, d_model)\n", + "\n", + "custom_pos_emb = SinusoidalPositionalEmbedding(d_model, max_seq_len)\n", + "\n", + "positional_encoding_custom = custom_pos_emb(positions)\n", + "\n", + "print(positional_encoding_custom.shape) # (1, 50, 64)\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/sinusoidal-q7.ipynb b/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb similarity index 100% rename from llm/sinusoidal-q7.ipynb rename to llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb diff --git a/llm/SmolLM/smollm-q12-Question.ipynb b/llm/SmolLM/smollm-q12-Question.ipynb new file mode 100644 index 0000000..4e2d1a2 --- /dev/null +++ b/llm/SmolLM/smollm-q12-Question.ipynb @@ -0,0 +1,63 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import math\n", + "import torch\n", + "from torch import nn\n", + "\n", + "# Helper function to rotate the last half of a tensor\n", + "# Used in rotary positional embeddings to compute sine and cosine rotations\n", + "def rotate_half(x):\n", + " # Split tensor into two halves along the last dimension\n", + " \n", + "\n", + "# Applies rotary positional embeddings to query (q) and key (k) tensors\n", + "# Uses sine and cosine positional encodings to enhance positional awareness\n", + "def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):\n", + " # Expand cos and sin tensors for broadcasting\n", + " \n", + "\n", + "# Repeats key-value tensors for multiple attention heads\n", + "# Ensures compatibility between the number of attention heads and key-value heads\n", + "def repeat_kv(hidden_states, n_rep):\n", + " \n", + " # Expand the number of key-value heads by repeating them\n", + " \n", + " # Reshape to align with the expected multi-head attention format\n", + " \n", + "\n", + "# Computes rotary positional embeddings for queries and keys\n", + "class RotaryEmbedder(nn.Module):\n", + " def __init__(self, dim, base):\n", + " \n", + "\n", + " @torch.no_grad()\n", + " def forward(self, x):\n", + " \n", + "\n", + "# Implements attention with rotary positional embeddings\n", + "class RopeAttention(nn.Module):\n", + " def __init__(self, config):\n", + " \n", + " self.rotary_emb = RotaryEmbedder(base=self.rope_theta, dim=self.head_dim)\n", + "\n", + " def forward(self, hidden_states: torch.Tensor, attention_mask=None):\n", + " # Input dimensions: (batch_size, seq_len, hidden_size)\n", + " \n", + " return attn_output" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/llm/smollm-q12.ipynb b/llm/SmolLM/smollm-q12.ipynb similarity index 99% rename from llm/smollm-q12.ipynb rename to llm/SmolLM/smollm-q12.ipynb index fe73296..03da883 100644 --- a/llm/smollm-q12.ipynb +++ b/llm/SmolLM/smollm-q12.ipynb @@ -14,6 +14,14 @@ "## Question" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "4e9fbe74", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "id": "3a697924", From 9677cd1a2896533f478dfb44c6aa9555471083d4 Mon Sep 17 00:00:00 2001 From: AtulAravindDas Date: Fri, 23 May 2025 20:30:15 -0400 Subject: [PATCH 20/40] Added the three dots --- llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb | 8 ++++---- .../embeddings-q2-Question.ipynb | 2 +- .../grouped-query-attention-Question.ipynb | 1 + .../attention-q4-Question.ipynb | 2 +- .../multi-head-attention-q5-Question.ipynb | 2 +- .../rope-q8-Question.ipynb | 5 ++--- .../sinusoidal-q7-Question.ipynb | 4 ++-- llm/SmolLM/smollm-q12-Question.ipynb | 16 ++++++++-------- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb b/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb index 6861832..ac089d0 100644 --- a/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb +++ b/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb @@ -40,22 +40,22 @@ "\n", "def get_vocab(corpus):\n", " \"\"\"Creates a vocabulary with words split into characters and a special end-of-word token.\"\"\"\n", - " \n", + " ...\n", " return vocab\n", "\n", "def get_stats(vocab):\n", " \"\"\"Counts frequency of adjacent symbol pairs.\"\"\"\n", - " \n", + " ...\n", " return pairs\n", "\n", "def merge_vocab(pair, vocab):\n", " \"\"\"Merges the most frequent pair into a single symbol.\"\"\"\n", - " \n", + " ...\n", " return new_vocab\n", "\n", "def byte_pair_encoding(corpus, num_merges=10):\n", " \"\"\"Performs BPE on a corpus.\"\"\"\n", - " \n", + " ...\n", " return vocab, merges\n", "\n", "# Example usage\n", diff --git a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb index 55d6507..412d3b5 100644 --- a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb +++ b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb @@ -100,7 +100,7 @@ "\n", "# Load model and tokenizer\n", "tokenizer = AutoTokenizer.from_pretrained(\"HuggingFaceTB/SmolLM2-135M\")\n", - "\n", + "...\n", "\n", "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", "model.to(device)" diff --git a/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb b/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb index 502e3b3..2ddbe3c 100644 --- a/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb +++ b/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb @@ -116,6 +116,7 @@ " Returns:\n", " Tensor: GQA output of shape (batch_size, seq_len, d_model)\n", " \"\"\"\n", + " ...\n", " " ] }, diff --git a/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb index a7826c2..33ddcb1 100644 --- a/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb +++ b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb @@ -92,7 +92,7 @@ " output: Attention output tensor of shape (..., seq_len_q, d_v)\n", " attention_weights: Attention weights tensor of shape (..., seq_len_q, seq_len_k)\n", " \"\"\"\n", - " " + " ..." ] }, { diff --git a/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb b/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb index 01c7f9a..45b45e1 100644 --- a/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb +++ b/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb @@ -118,7 +118,7 @@ " Returns:\n", " Tensor: Multi-head attention output of shape (batch_size, seq_len, d_model)\n", " \"\"\"\n", - " " + " ..." ] }, { diff --git a/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb b/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb index 2462bb4..1a64ef4 100644 --- a/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb +++ b/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb @@ -101,12 +101,11 @@ "class Rotary(torch.nn.Module):\n", " \n", "def rotate_half(x):\n", - " \n", - "\n", + " ...\n", "\n", "@torch.jit.script\n", "def apply_rotary_pos_emb(q, k, cos, sin):\n", - " " + " ..." ] }, { diff --git a/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb b/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb index 93657f1..ed3ee3a 100644 --- a/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb +++ b/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb @@ -103,7 +103,7 @@ " max_seq_len (int): Maximum sequence length.\n", " d_model (int): Embedding dimension.\n", " \"\"\"\n", - " \n", + " ...\n", "\n", " def forward(self, x):\n", " \"\"\"\n", @@ -115,7 +115,7 @@ " Returns:\n", " Tensor: Positional embeddings of shape (batch_size, seq_len, d_model).\n", " \"\"\"\n", - " " + " ..." ] }, { diff --git a/llm/SmolLM/smollm-q12-Question.ipynb b/llm/SmolLM/smollm-q12-Question.ipynb index 4e2d1a2..d931f83 100644 --- a/llm/SmolLM/smollm-q12-Question.ipynb +++ b/llm/SmolLM/smollm-q12-Question.ipynb @@ -14,40 +14,40 @@ "# Used in rotary positional embeddings to compute sine and cosine rotations\n", "def rotate_half(x):\n", " # Split tensor into two halves along the last dimension\n", - " \n", - "\n", + " ...\n", "# Applies rotary positional embeddings to query (q) and key (k) tensors\n", "# Uses sine and cosine positional encodings to enhance positional awareness\n", "def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):\n", " # Expand cos and sin tensors for broadcasting\n", - " \n", + " ...\n", "\n", "# Repeats key-value tensors for multiple attention heads\n", "# Ensures compatibility between the number of attention heads and key-value heads\n", "def repeat_kv(hidden_states, n_rep):\n", " \n", " # Expand the number of key-value heads by repeating them\n", - " \n", + " ...\n", " # Reshape to align with the expected multi-head attention format\n", - " \n", + " ...\n", "\n", "# Computes rotary positional embeddings for queries and keys\n", "class RotaryEmbedder(nn.Module):\n", " def __init__(self, dim, base):\n", - " \n", + " ...\n", "\n", " @torch.no_grad()\n", " def forward(self, x):\n", - " \n", + " ...\n", "\n", "# Implements attention with rotary positional embeddings\n", "class RopeAttention(nn.Module):\n", " def __init__(self, config):\n", " \n", " self.rotary_emb = RotaryEmbedder(base=self.rope_theta, dim=self.head_dim)\n", - "\n", + " ...\n", " def forward(self, hidden_states: torch.Tensor, attention_mask=None):\n", " # Input dimensions: (batch_size, seq_len, hidden_size)\n", + " ...\n", " \n", " return attn_output" ] From ced93d63767cc40acd3e4b30b359f36467d2c6cc Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sat, 24 May 2025 09:12:52 -0700 Subject: [PATCH 21/40] Clean up --- README.md | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/README.md b/README.md index 8e3a3ea..75dec4e 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,7 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st **An all new set of questions to help you understand and implement Large Language Models from scratch.** 1. Implement KL Divergence Loss -2. Implement RMS Norm -<<<<<<< HEAD +2. Implement RMS ~~Norm~~ 3. [Implement Byte Pair Encoding from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3.ipynb) 4. [Create an embeddings out of an LLM](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) 5. Implement Predictive Prefill with Speculative Decoding @@ -81,18 +80,6 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 10. [Implement Sinusoidal Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) 11. [Implement ROPE Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8.ipynb) 12. [Implement SmolLM from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12.ipynb) -======= -3. [Implement Byte Pair Encoding from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/BPE-q3.ipynb) -4. [Create an embeddings out of an LLM](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/embeddings-q2.ipynb) -5. Implement Predictive Prefill with Speculative Decoding -6. [Implement Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/attention-q4.ipynb) -7. [Implement Multi-Head Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/multi-head-attention-q5.ipynb) -8. [Implement Grouped Query Attention from Scratch](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/grouped-query-attention.ipynb) -9. Implement KV Cache in Multi-Head Attention from Scratch -10. [Implement Sinusoidal Embeddings](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/sinusoidal-q7.ipynb) -11. [Implement ROPE Embeddings](https://github.com/AtulAravindDas/TorchLeet/blob/ff5b96d6f99ccdc7d94e86efe873875065107754/llm/rope-q8.ipynb) -12. Implement SmolLM from Scratch ->>>>>>> f7ccb8c2d0e1fa785455ec89f792cf8b607ac936 13. Implement Quantization of Models a. Types of Quantization 14. Implement Beam Search atop LLM for decoding From 3d574f6efcaaa0dd620dee5c5ca1fc82dbf1f835 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sat, 24 May 2025 10:45:23 -0700 Subject: [PATCH 22/40] Cleanup --- CheatSheet.md | 2 ++ README.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 CheatSheet.md diff --git a/CheatSheet.md b/CheatSheet.md new file mode 100644 index 0000000..3d52704 --- /dev/null +++ b/CheatSheet.md @@ -0,0 +1,2 @@ +# Cheat Sheet for PyTorch + diff --git a/README.md b/README.md index 75dec4e..63f3d62 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@
-TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-style challenges, designed to enhance your skills in deep learning and PyTorch. NOW WITH LLMS! +TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-style challenges, designed to enhance your skills in deep learning and PyTorch. **NOW WITH LLMS!** ## Table of Contents - [TorchLeet](#torchleet) @@ -51,6 +51,8 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) 7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) +** Finding these too easy? Try implementing from scratch in empty ntbk** + ### ๐Ÿ”ดHard 1. [Write a custom Autograd function for activation (SILU)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function_SOLN.ipynb) 2. Write a Neural Style Transfer From bdacc7e97c80ed92b29445f6b505939be03a3074 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sat, 24 May 2025 11:07:40 -0700 Subject: [PATCH 23/40] Cleanup lstm problem --- torch/medium/m1/LSTM.ipynb | 91 +++++++++++++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 11 deletions(-) diff --git a/torch/medium/m1/LSTM.ipynb b/torch/medium/m1/LSTM.ipynb index 4b8829a..53d589e 100644 --- a/torch/medium/m1/LSTM.ipynb +++ b/torch/medium/m1/LSTM.ipynb @@ -73,6 +73,20 @@ "X_seq, y_seq = create_in_out_sequences(y, sequence_length)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class CustomLSTMModel(nn.Module):\n", + " def __init__(self, input_dim, hidden_units):\n", + " ...\n", + " \n", + " def forward(self, inputs, H_C=None):\n", + " ..." + ] + }, { "cell_type": "code", "execution_count": 9, @@ -95,7 +109,21 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Initialize the model, loss function, and optimizer\n", + "model_custom = CustomLSTMModel(1, 50)\n", + "model_inbuilt = LSTMModel()\n", + "criterion = nn.MSELoss()\n", + "optimizer_custom = optim.Adam(model_custom.parameters(), lr=0.01)\n", + "optimizer_inbuilt = optim.Adam(model_inbuilt.parameters(), lr=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": null, "metadata": {}, "outputs": [ { @@ -116,17 +144,39 @@ } ], "source": [ - "# Training loop\n", + "# Training loop for the custom model\n", "epochs = 500\n", "for epoch in range(epochs):\n", " # Forward pass\n", - " predictions = model(X_seq)\n", - " loss = criterion(predictions, y_seq)\n", + " state = None\n", + " pred, state = model_custom(X_seq, state)\n", + " loss = criterion(pred[:, -1, :], y_seq) # Use the last output of the LSTM\n", + " # Backward pass and optimization\n", + " optimizer_custom.zero_grad()\n", + " loss.backward()\n", + " optimizer_custom.step()\n", "\n", + " # Log progress every 50 epochs\n", + " if (epoch + 1) % 50 == 0:\n", + " print(f\"Epoch [{epoch + 1}/{epochs}], Loss: {loss.item():.4f}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Training loop for the inbuilt model\n", + "epochs = 500\n", + "for epoch in range(epochs):\n", + " # Forward pass\n", + " pred = model_inbuilt(X_seq)\n", + " loss = criterion(pred, y_seq)\n", " # Backward pass and optimization\n", - " optimizer.zero_grad()\n", + " optimizer_inbuilt.zero_grad()\n", " loss.backward()\n", - " optimizer.step()\n", + " optimizer_inbuilt.step()\n", "\n", " # Log progress every 50 epochs\n", " if (epoch + 1) % 50 == 0:\n", @@ -135,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -148,16 +198,35 @@ ], "source": [ "# Testing on new data\n", - "test_steps = 20 # Ensure this is greater than sequence_length\n", - "X_test = torch.linspace(4 * 3.14159, 5 * 3.14159, steps=test_steps).unsqueeze(1)\n", + "test_steps = 100 # Ensure this is greater than sequence_length\n", + "X_test = torch.linspace(0, 5 * 3.14159, steps=test_steps).unsqueeze(1)\n", "y_test = torch.sin(X_test)\n", "\n", "# Create test input sequences\n", "X_test_seq, _ = create_in_out_sequences(y_test, sequence_length)\n", "\n", "with torch.no_grad():\n", - " predictions = model(X_test_seq)\n", - " print(f\"Predictions for new sequence: {predictions.squeeze().tolist()}\")\n" + " pred_custom, _ = model_custom(X_test_seq)\n", + " pred_inbuilt = model_inbuilt(X_test_seq)\n", + "pred_custom = torch.flatten(pred_custom[:, -1, :])\n", + "pred_inbuilt = pred_inbuilt.squeeze()\n", + "print(f\"Predictions with Custom Model for new sequence: {pred_custom.tolist()}\")\n", + "print(f\"Predictions with In-Built Model: {pred_inbuilt.tolist()}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#Plot the predictions\n", + "plt.figure()\n", + "# plt.plot(y_test, label=\"Ground Truth\")\n", + "plt.plot(pred_custom, label=\"custom model\")\n", + "plt.plot(pred_inbuilt, label=\"inbuilt model\")\n", + "plt.legend()\n", + "plt.show()" ] } ], From 6934127a23ccaf4543cb52cc64bd93802ff53278 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 25 May 2025 11:38:12 -0700 Subject: [PATCH 24/40] Question Update --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 63f3d62..c789590 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,8 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 4. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) 5. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) 6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) -7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) +7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) +8. Implement AlexNet from scratch ** Finding these too easy? Try implementing from scratch in empty ntbk** From b14d9e49abe870398d549cb6edb62c6e4e13a1ce Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 25 May 2025 11:46:18 -0700 Subject: [PATCH 25/40] new q --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c789590..4c9e69d 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) 7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) 8. Implement AlexNet from scratch +9. Build a Dense Retrieval System using PyTorch ** Finding these too easy? Try implementing from scratch in empty ntbk** From 463e87dba67297d2538f7f129ef4fee1174f44fc Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 25 May 2025 15:11:32 -0700 Subject: [PATCH 26/40] From Scratch Implementation RNN --- torch/medium/m4/RNN_SOLN.ipynb | 603 +++++---------------------------- 1 file changed, 89 insertions(+), 514 deletions(-) diff --git a/torch/medium/m4/RNN_SOLN.ipynb b/torch/medium/m4/RNN_SOLN.ipynb index 727b401..d6524c2 100644 --- a/torch/medium/m4/RNN_SOLN.ipynb +++ b/torch/medium/m4/RNN_SOLN.ipynb @@ -28,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -66,533 +66,108 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# Define the RNN Model\n", "class RNNModel(nn.Module):\n", - " def __init__(self):\n", - " super(RNNModel, self).__init__()\n", - " self.rnn = nn.RNN(input_size=1, hidden_size=50, num_layers=1, batch_first=True)\n", - " self.fc = nn.Linear(50, 1)\n", - " self.relu = nn.ReLU()\n", + " def __init__(self, input_dim=1, hidden_dim=50, output_dim=1):\n", + " super().__init__()\n", + " self.hidden_dim = hidden_dim\n", + "\n", + " # Weight matrices for input and hidden state\n", + " self.W_ih = nn.Parameter(torch.randn(input_dim, hidden_dim) * 0.1)\n", + " self.W_hh = nn.Parameter(torch.randn(hidden_dim, hidden_dim) * 0.1)\n", + " self.b_h = nn.Parameter(torch.zeros(hidden_dim))\n", + "\n", + " # Output layer\n", + " self.output_layer = nn.Linear(hidden_dim, output_dim)\n", + "\n", + " # Activation\n", + " self.tanh = nn.Tanh()\n", "\n", " def forward(self, x):\n", - " out, _ = self.rnn(x)\n", - " out = self.fc(out[:, -1, :]) # Use the last output of the RNN\n", - " return out" + " batch_size, seq_len, _ = x.size()\n", + " h_t = torch.zeros(batch_size, self.hidden_dim, device=x.device)\n", + "\n", + " for t in range(seq_len):\n", + " x_t = x[:, t, :]\n", + " h_t = self.tanh(x_t @ self.W_ih + h_t @ self.W_hh + self.b_h)\n", + "\n", + " output = self.output_layer(h_t)\n", + " return output\n" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch [1/500], Loss: 0.1162\n", - "Epoch [2/500], Loss: 0.0031\n", - "Epoch [3/500], Loss: 0.0095\n", - "Epoch [4/500], Loss: 0.0002\n", - "Epoch [5/500], Loss: 0.0000\n", - "Epoch [6/500], Loss: 0.0268\n", - "Epoch [7/500], Loss: 0.0165\n", - "Epoch [8/500], Loss: 0.0763\n", - "Epoch [9/500], Loss: 0.0163\n", - "Epoch [10/500], Loss: 0.0008\n", - "Epoch [11/500], Loss: 0.0009\n", - "Epoch [12/500], Loss: 0.0009\n", - "Epoch [13/500], Loss: 0.0016\n", + "Epoch [1/500], Loss: 0.0721\n", + "Epoch [2/500], Loss: 0.0034\n", + "Epoch [3/500], Loss: 0.0746\n", + "Epoch [4/500], Loss: 0.0022\n", + "Epoch [5/500], Loss: 0.0521\n", + "Epoch [6/500], Loss: 0.0001\n", + "Epoch [7/500], Loss: 0.0048\n", + "Epoch [8/500], Loss: 0.0160\n", + "Epoch [9/500], Loss: 0.0002\n", + "Epoch [10/500], Loss: 0.0002\n", + "Epoch [11/500], Loss: 0.0005\n", + "Epoch [12/500], Loss: 0.0004\n", + "Epoch [13/500], Loss: 0.0000\n", "Epoch [14/500], Loss: 0.0000\n", - "Epoch [15/500], Loss: 0.0008\n", - "Epoch [16/500], Loss: 0.0003\n", - "Epoch [17/500], Loss: 0.0004\n", - "Epoch [18/500], Loss: 0.0028\n", - "Epoch [19/500], Loss: 0.0062\n", - "Epoch [20/500], Loss: 0.0022\n", - "Epoch [21/500], Loss: 0.0046\n", - "Epoch [22/500], Loss: 0.0066\n", - "Epoch [23/500], Loss: 0.0072\n", - "Epoch [24/500], Loss: 0.0083\n", - "Epoch [25/500], Loss: 0.0089\n", - "Epoch [26/500], Loss: 0.0073\n", - "Epoch [27/500], Loss: 0.0053\n", - "Epoch [28/500], Loss: 0.0048\n", - "Epoch [29/500], Loss: 0.0043\n", - "Epoch [30/500], Loss: 0.0040\n", - "Epoch [31/500], Loss: 0.0034\n", - "Epoch [32/500], Loss: 0.0027\n", - "Epoch [33/500], Loss: 0.0016\n", - "Epoch [34/500], Loss: 0.0004\n", - "Epoch [35/500], Loss: 0.0002\n", - "Epoch [36/500], Loss: 0.0002\n", - "Epoch [37/500], Loss: 0.0002\n", - "Epoch [38/500], Loss: 0.0067\n", - "Epoch [39/500], Loss: 0.0180\n", - "Epoch [40/500], Loss: 0.0259\n", - "Epoch [41/500], Loss: 0.0022\n", - "Epoch [42/500], Loss: 0.0032\n", - "Epoch [43/500], Loss: 0.0003\n", - "Epoch [44/500], Loss: 0.0006\n", - "Epoch [45/500], Loss: 0.0007\n", - "Epoch [46/500], Loss: 0.0001\n", - "Epoch [47/500], Loss: 0.0000\n", - "Epoch [48/500], Loss: 0.0008\n", - "Epoch [49/500], Loss: 0.0057\n", - "Epoch [50/500], Loss: 0.0056\n", - "Epoch [51/500], Loss: 0.0005\n", - "Epoch [52/500], Loss: 0.0030\n", - "Epoch [53/500], Loss: 0.0075\n", - "Epoch [54/500], Loss: 0.0046\n", - "Epoch [55/500], Loss: 0.0035\n", - "Epoch [56/500], Loss: 0.0001\n", - "Epoch [57/500], Loss: 0.0051\n", - "Epoch [58/500], Loss: 0.0029\n", - "Epoch [59/500], Loss: 0.0026\n", - "Epoch [60/500], Loss: 0.0005\n", - "Epoch [61/500], Loss: 0.0000\n", - "Epoch [62/500], Loss: 0.0001\n", - "Epoch [63/500], Loss: 0.0001\n", - "Epoch [64/500], Loss: 0.0001\n", - "Epoch [65/500], Loss: 0.0001\n", - "Epoch [66/500], Loss: 0.0000\n", - "Epoch [67/500], Loss: 0.0000\n", - "Epoch [68/500], Loss: 0.0002\n", - "Epoch [69/500], Loss: 0.0007\n", - "Epoch [70/500], Loss: 0.0011\n", - "Epoch [71/500], Loss: 0.0012\n", - "Epoch [72/500], Loss: 0.0010\n", - "Epoch [73/500], Loss: 0.0005\n", - "Epoch [74/500], Loss: 0.0002\n", - "Epoch [75/500], Loss: 0.0001\n", - "Epoch [76/500], Loss: 0.0000\n", - "Epoch [77/500], Loss: 0.0000\n", - "Epoch [78/500], Loss: 0.0000\n", - "Epoch [79/500], Loss: 0.0001\n", - "Epoch [80/500], Loss: 0.0002\n", - "Epoch [81/500], Loss: 0.0005\n", - "Epoch [82/500], Loss: 0.0010\n", - "Epoch [83/500], Loss: 0.0018\n", - "Epoch [84/500], Loss: 0.0007\n", - "Epoch [85/500], Loss: 0.0012\n", - "Epoch [86/500], Loss: 0.0049\n", - "Epoch [87/500], Loss: 0.0003\n", - "Epoch [88/500], Loss: 0.0001\n", - "Epoch [89/500], Loss: 0.0025\n", - "Epoch [90/500], Loss: 0.0013\n", - "Epoch [91/500], Loss: 0.0001\n", - "Epoch [92/500], Loss: 0.0001\n", - "Epoch [93/500], Loss: 0.0010\n", - "Epoch [94/500], Loss: 0.0000\n", - "Epoch [95/500], Loss: 0.0020\n", - "Epoch [96/500], Loss: 0.0003\n", - "Epoch [97/500], Loss: 0.0131\n", - "Epoch [98/500], Loss: 0.0003\n", - "Epoch [99/500], Loss: 0.0017\n", - "Epoch [100/500], Loss: 0.0002\n", - "Epoch [101/500], Loss: 0.0000\n", - "Epoch [102/500], Loss: 0.0000\n", - "Epoch [103/500], Loss: 0.0004\n", - "Epoch [104/500], Loss: 0.0017\n", - "Epoch [105/500], Loss: 0.0047\n", - "Epoch [106/500], Loss: 0.0095\n", - "Epoch [107/500], Loss: 0.0045\n", - "Epoch [108/500], Loss: 0.0045\n", - "Epoch [109/500], Loss: 0.0018\n", - "Epoch [110/500], Loss: 0.0005\n", - "Epoch [111/500], Loss: 0.0001\n", - "Epoch [112/500], Loss: 0.0001\n", - "Epoch [113/500], Loss: 0.0002\n", - "Epoch [114/500], Loss: 0.0004\n", - "Epoch [115/500], Loss: 0.0004\n", - "Epoch [116/500], Loss: 0.0002\n", - "Epoch [117/500], Loss: 0.0000\n", - "Epoch [118/500], Loss: 0.0000\n", - "Epoch [119/500], Loss: 0.0001\n", - "Epoch [120/500], Loss: 0.0030\n", - "Epoch [121/500], Loss: 0.0084\n", - "Epoch [122/500], Loss: 0.0051\n", - "Epoch [123/500], Loss: 0.0042\n", - "Epoch [124/500], Loss: 0.0004\n", - "Epoch [125/500], Loss: 0.0003\n", - "Epoch [126/500], Loss: 0.0192\n", - "Epoch [127/500], Loss: 0.0000\n", - "Epoch [128/500], Loss: 0.0061\n", - "Epoch [129/500], Loss: 0.0000\n", - "Epoch [130/500], Loss: 0.0004\n", - "Epoch [131/500], Loss: 0.0019\n", - "Epoch [132/500], Loss: 0.0020\n", - "Epoch [133/500], Loss: 0.0012\n", - "Epoch [134/500], Loss: 0.0003\n", - "Epoch [135/500], Loss: 0.0000\n", - "Epoch [136/500], Loss: 0.0003\n", - "Epoch [137/500], Loss: 0.0038\n", - "Epoch [138/500], Loss: 0.0009\n", - "Epoch [139/500], Loss: 0.0000\n", - "Epoch [140/500], Loss: 0.0004\n", - "Epoch [141/500], Loss: 0.0065\n", - "Epoch [142/500], Loss: 0.0117\n", - "Epoch [143/500], Loss: 0.0004\n", - "Epoch [144/500], Loss: 0.0092\n", - "Epoch [145/500], Loss: 0.0001\n", - "Epoch [146/500], Loss: 0.0009\n", - "Epoch [147/500], Loss: 0.0000\n", - "Epoch [148/500], Loss: 0.0001\n", - "Epoch [149/500], Loss: 0.0007\n", - "Epoch [150/500], Loss: 0.0021\n", - "Epoch [151/500], Loss: 0.0021\n", - "Epoch [152/500], Loss: 0.0061\n", - "Epoch [153/500], Loss: 0.0019\n", - "Epoch [154/500], Loss: 0.0045\n", - "Epoch [155/500], Loss: 0.0026\n", - "Epoch [156/500], Loss: 0.0000\n", - "Epoch [157/500], Loss: 0.0000\n", - "Epoch [158/500], Loss: 0.0003\n", - "Epoch [159/500], Loss: 0.0003\n", - "Epoch [160/500], Loss: 0.0004\n", - "Epoch [161/500], Loss: 0.0005\n", - "Epoch [162/500], Loss: 0.0006\n", - "Epoch [163/500], Loss: 0.0003\n", - "Epoch [164/500], Loss: 0.0026\n", - "Epoch [165/500], Loss: 0.0002\n", - "Epoch [166/500], Loss: 0.0001\n", - "Epoch [167/500], Loss: 0.0008\n", - "Epoch [168/500], Loss: 0.0022\n", - "Epoch [169/500], Loss: 0.0000\n", - "Epoch [170/500], Loss: 0.0018\n", - "Epoch [171/500], Loss: 0.0055\n", - "Epoch [172/500], Loss: 0.0003\n", - "Epoch [173/500], Loss: 0.0000\n", - "Epoch [174/500], Loss: 0.0050\n", - "Epoch [175/500], Loss: 0.0025\n", - "Epoch [176/500], Loss: 0.0003\n", - "Epoch [177/500], Loss: 0.0008\n", - "Epoch [178/500], Loss: 0.0017\n", - "Epoch [179/500], Loss: 0.0000\n", - "Epoch [180/500], Loss: 0.0019\n", - "Epoch [181/500], Loss: 0.0001\n", - "Epoch [182/500], Loss: 0.0000\n", - "Epoch [183/500], Loss: 0.0001\n", - "Epoch [184/500], Loss: 0.0003\n", - "Epoch [185/500], Loss: 0.0003\n", - "Epoch [186/500], Loss: 0.0001\n", - "Epoch [187/500], Loss: 0.0017\n", - "Epoch [188/500], Loss: 0.0021\n", - "Epoch [189/500], Loss: 0.0009\n", - "Epoch [190/500], Loss: 0.0001\n", - "Epoch [191/500], Loss: 0.0008\n", - "Epoch [192/500], Loss: 0.0000\n", - "Epoch [193/500], Loss: 0.0004\n", - "Epoch [194/500], Loss: 0.0001\n", - "Epoch [195/500], Loss: 0.0002\n", - "Epoch [196/500], Loss: 0.0001\n", - "Epoch [197/500], Loss: 0.0004\n", - "Epoch [198/500], Loss: 0.0022\n", - "Epoch [199/500], Loss: 0.0009\n", - "Epoch [200/500], Loss: 0.0002\n", - "Epoch [201/500], Loss: 0.0505\n", - "Epoch [202/500], Loss: 0.7340\n", - "Epoch [203/500], Loss: 0.0394\n", - "Epoch [204/500], Loss: 0.0000\n", - "Epoch [205/500], Loss: 0.0001\n", - "Epoch [206/500], Loss: 0.0161\n", - "Epoch [207/500], Loss: 0.0003\n", - "Epoch [208/500], Loss: 0.0233\n", - "Epoch [209/500], Loss: 0.0770\n", - "Epoch [210/500], Loss: 0.0126\n", - "Epoch [211/500], Loss: 0.0002\n", - "Epoch [212/500], Loss: 0.0004\n", - "Epoch [213/500], Loss: 0.0000\n", - "Epoch [214/500], Loss: 0.0004\n", - "Epoch [215/500], Loss: 0.0018\n", - "Epoch [216/500], Loss: 0.0010\n", - "Epoch [217/500], Loss: 0.0000\n", - "Epoch [218/500], Loss: 0.0000\n", - "Epoch [219/500], Loss: 0.0052\n", - "Epoch [220/500], Loss: 0.0120\n", - "Epoch [221/500], Loss: 0.0023\n", - "Epoch [222/500], Loss: 0.0000\n", - "Epoch [223/500], Loss: 0.0005\n", - "Epoch [224/500], Loss: 0.0008\n", - "Epoch [225/500], Loss: 0.0007\n", - "Epoch [226/500], Loss: 0.0005\n", - "Epoch [227/500], Loss: 0.0003\n", - "Epoch [228/500], Loss: 0.0000\n", - "Epoch [229/500], Loss: 0.0008\n", - "Epoch [230/500], Loss: 0.0008\n", - "Epoch [231/500], Loss: 0.0000\n", - "Epoch [232/500], Loss: 0.0000\n", - "Epoch [233/500], Loss: 0.0001\n", - "Epoch [234/500], Loss: 0.0000\n", - "Epoch [235/500], Loss: 0.0000\n", - "Epoch [236/500], Loss: 0.0000\n", - "Epoch [237/500], Loss: 0.0000\n", - "Epoch [238/500], Loss: 0.0001\n", - "Epoch [239/500], Loss: 0.0009\n", - "Epoch [240/500], Loss: 0.0049\n", - "Epoch [241/500], Loss: 0.0030\n", - "Epoch [242/500], Loss: 0.0009\n", - "Epoch [243/500], Loss: 0.0011\n", - "Epoch [244/500], Loss: 0.0000\n", - "Epoch [245/500], Loss: 0.0014\n", - "Epoch [246/500], Loss: 0.0039\n", - "Epoch [247/500], Loss: 0.0014\n", - "Epoch [248/500], Loss: 0.0019\n", - "Epoch [249/500], Loss: 0.0000\n", - "Epoch [250/500], Loss: 0.0028\n", - "Epoch [251/500], Loss: 0.0016\n", - "Epoch [252/500], Loss: 0.0044\n", - "Epoch [253/500], Loss: 0.0016\n", - "Epoch [254/500], Loss: 0.0003\n", - "Epoch [255/500], Loss: 0.0067\n", - "Epoch [256/500], Loss: 0.0000\n", - "Epoch [257/500], Loss: 0.0005\n", - "Epoch [258/500], Loss: 0.0015\n", - "Epoch [259/500], Loss: 0.0008\n", - "Epoch [260/500], Loss: 0.0022\n", - "Epoch [261/500], Loss: 0.0152\n", - "Epoch [262/500], Loss: 0.0029\n", - "Epoch [263/500], Loss: 0.0001\n", - "Epoch [264/500], Loss: 0.0000\n", - "Epoch [265/500], Loss: 0.0001\n", - "Epoch [266/500], Loss: 0.0001\n", - "Epoch [267/500], Loss: 0.0000\n", - "Epoch [268/500], Loss: 0.0015\n", - "Epoch [269/500], Loss: 0.0071\n", - "Epoch [270/500], Loss: 0.0047\n", - "Epoch [271/500], Loss: 0.0011\n", - "Epoch [272/500], Loss: 0.0017\n", - "Epoch [273/500], Loss: 0.0014\n", - "Epoch [274/500], Loss: 0.0007\n", - "Epoch [275/500], Loss: 0.0002\n", - "Epoch [276/500], Loss: 0.0002\n", - "Epoch [277/500], Loss: 0.0002\n", - "Epoch [278/500], Loss: 0.0006\n", - "Epoch [279/500], Loss: 0.0010\n", - "Epoch [280/500], Loss: 0.0003\n", - "Epoch [281/500], Loss: 0.0000\n", - "Epoch [282/500], Loss: 0.0002\n", - "Epoch [283/500], Loss: 0.0017\n", - "Epoch [284/500], Loss: 0.0054\n", - "Epoch [285/500], Loss: 0.0003\n", - "Epoch [286/500], Loss: 0.0035\n", - "Epoch [287/500], Loss: 0.0013\n", - "Epoch [288/500], Loss: 0.0210\n", - "Epoch [289/500], Loss: 0.0003\n", - "Epoch [290/500], Loss: 0.0045\n", - "Epoch [291/500], Loss: 0.0007\n", - "Epoch [292/500], Loss: 0.0001\n", - "Epoch [293/500], Loss: 0.0000\n", - "Epoch [294/500], Loss: 0.0001\n", - "Epoch [295/500], Loss: 0.0000\n", - "Epoch [296/500], Loss: 0.0006\n", - "Epoch [297/500], Loss: 0.0002\n", - "Epoch [298/500], Loss: 0.0000\n", - "Epoch [299/500], Loss: 0.0016\n", - "Epoch [300/500], Loss: 0.0065\n", - "Epoch [301/500], Loss: 0.0015\n", - "Epoch [302/500], Loss: 0.0071\n", - "Epoch [303/500], Loss: 0.0079\n", - "Epoch [304/500], Loss: 0.0051\n", - "Epoch [305/500], Loss: 0.0080\n", - "Epoch [306/500], Loss: 0.0010\n", - "Epoch [307/500], Loss: 0.0011\n", - "Epoch [308/500], Loss: 0.0010\n", - "Epoch [309/500], Loss: 0.0001\n", - "Epoch [310/500], Loss: 0.0013\n", - "Epoch [311/500], Loss: 0.0056\n", - "Epoch [312/500], Loss: 0.0021\n", - "Epoch [313/500], Loss: 0.0004\n", - "Epoch [314/500], Loss: 0.0006\n", - "Epoch [315/500], Loss: 0.0000\n", - "Epoch [316/500], Loss: 0.0006\n", - "Epoch [317/500], Loss: 0.0047\n", - "Epoch [318/500], Loss: 0.0024\n", - "Epoch [319/500], Loss: 0.0009\n", - "Epoch [320/500], Loss: 0.0029\n", - "Epoch [321/500], Loss: 0.0000\n", - "Epoch [322/500], Loss: 0.0005\n", - "Epoch [323/500], Loss: 0.0000\n", - "Epoch [324/500], Loss: 0.0000\n", - "Epoch [325/500], Loss: 0.0001\n", - "Epoch [326/500], Loss: 0.0002\n", - "Epoch [327/500], Loss: 0.0001\n", - "Epoch [328/500], Loss: 0.0006\n", - "Epoch [329/500], Loss: 0.0003\n", - "Epoch [330/500], Loss: 0.0060\n", - "Epoch [331/500], Loss: 0.0001\n", - "Epoch [332/500], Loss: 0.0004\n", - "Epoch [333/500], Loss: 0.0000\n", - "Epoch [334/500], Loss: 0.0008\n", - "Epoch [335/500], Loss: 0.0087\n", - "Epoch [336/500], Loss: 0.0066\n", - "Epoch [337/500], Loss: 0.0015\n", - "Epoch [338/500], Loss: 0.0094\n", - "Epoch [339/500], Loss: 0.0028\n", - "Epoch [340/500], Loss: 0.0197\n", - "Epoch [341/500], Loss: 0.0002\n", - "Epoch [342/500], Loss: 0.0015\n", - "Epoch [343/500], Loss: 0.0003\n", - "Epoch [344/500], Loss: 0.0000\n", - "Epoch [345/500], Loss: 0.0000\n", - "Epoch [346/500], Loss: 0.0001\n", - "Epoch [347/500], Loss: 0.0000\n", - "Epoch [348/500], Loss: 0.0000\n", - "Epoch [349/500], Loss: 0.0000\n", - "Epoch [350/500], Loss: 0.0001\n", - "Epoch [351/500], Loss: 0.0000\n", - "Epoch [352/500], Loss: 0.0002\n", - "Epoch [353/500], Loss: 0.0005\n", - "Epoch [354/500], Loss: 0.0019\n", - "Epoch [355/500], Loss: 0.0014\n", - "Epoch [356/500], Loss: 0.0009\n", - "Epoch [357/500], Loss: 0.0011\n", - "Epoch [358/500], Loss: 0.0039\n", - "Epoch [359/500], Loss: 0.0029\n", - "Epoch [360/500], Loss: 0.0019\n", - "Epoch [361/500], Loss: 0.0059\n", - "Epoch [362/500], Loss: 0.0063\n", - "Epoch [363/500], Loss: 0.0001\n", - "Epoch [364/500], Loss: 0.0007\n", - "Epoch [365/500], Loss: 0.0027\n", - "Epoch [366/500], Loss: 0.0022\n", - "Epoch [367/500], Loss: 0.0001\n", - "Epoch [368/500], Loss: 0.0057\n", - "Epoch [369/500], Loss: 0.0052\n", - "Epoch [370/500], Loss: 0.0066\n", - "Epoch [371/500], Loss: 0.0001\n", - "Epoch [372/500], Loss: 0.0027\n", - "Epoch [373/500], Loss: 0.0047\n", - "Epoch [374/500], Loss: 0.0000\n", - "Epoch [375/500], Loss: 0.0002\n", - "Epoch [376/500], Loss: 0.0014\n", - "Epoch [377/500], Loss: 0.0035\n", - "Epoch [378/500], Loss: 0.0013\n", - "Epoch [379/500], Loss: 0.0008\n", - "Epoch [380/500], Loss: 0.0027\n", - "Epoch [381/500], Loss: 0.0000\n", - "Epoch [382/500], Loss: 0.0007\n", - "Epoch [383/500], Loss: 0.0019\n", - "Epoch [384/500], Loss: 0.0000\n", - "Epoch [385/500], Loss: 0.0035\n", - "Epoch [386/500], Loss: 0.0003\n", - "Epoch [387/500], Loss: 0.0003\n", - "Epoch [388/500], Loss: 0.0052\n", - "Epoch [389/500], Loss: 0.0043\n", - "Epoch [390/500], Loss: 0.0022\n", - "Epoch [391/500], Loss: 0.0000\n", - "Epoch [392/500], Loss: 0.0120\n", - "Epoch [393/500], Loss: 0.0002\n", - "Epoch [394/500], Loss: 0.0035\n", - "Epoch [395/500], Loss: 0.0002\n", - "Epoch [396/500], Loss: 0.0013\n", - "Epoch [397/500], Loss: 0.0052\n", - "Epoch [398/500], Loss: 0.0042\n", - "Epoch [399/500], Loss: 0.0022\n", - "Epoch [400/500], Loss: 0.0049\n", - "Epoch [401/500], Loss: 0.0052\n", - "Epoch [402/500], Loss: 0.0066\n", - "Epoch [403/500], Loss: 0.0009\n", - "Epoch [404/500], Loss: 0.0001\n", - "Epoch [405/500], Loss: 0.0001\n", - "Epoch [406/500], Loss: 0.0003\n", - "Epoch [407/500], Loss: 0.0012\n", - "Epoch [408/500], Loss: 0.0030\n", - "Epoch [409/500], Loss: 0.0028\n", - "Epoch [410/500], Loss: 0.0016\n", - "Epoch [411/500], Loss: 0.0001\n", - "Epoch [412/500], Loss: 0.0007\n", - "Epoch [413/500], Loss: 0.0000\n", - "Epoch [414/500], Loss: 0.0002\n", - "Epoch [415/500], Loss: 0.0029\n", - "Epoch [416/500], Loss: 0.0053\n", - "Epoch [417/500], Loss: 0.0023\n", - "Epoch [418/500], Loss: 0.0023\n", - "Epoch [419/500], Loss: 0.0000\n", - "Epoch [420/500], Loss: 0.0017\n", - "Epoch [421/500], Loss: 0.0000\n", - "Epoch [422/500], Loss: 0.0018\n", - "Epoch [423/500], Loss: 0.0008\n", - "Epoch [424/500], Loss: 0.0024\n", - "Epoch [425/500], Loss: 0.0027\n", - "Epoch [426/500], Loss: 0.0014\n", - "Epoch [427/500], Loss: 0.0031\n", - "Epoch [428/500], Loss: 0.0005\n", - "Epoch [429/500], Loss: 0.0060\n", - "Epoch [430/500], Loss: 0.0006\n", - "Epoch [431/500], Loss: 0.0031\n", - "Epoch [432/500], Loss: 0.0011\n", - "Epoch [433/500], Loss: 0.0000\n", - "Epoch [434/500], Loss: 0.0006\n", - "Epoch [435/500], Loss: 0.0015\n", - "Epoch [436/500], Loss: 0.0001\n", - "Epoch [437/500], Loss: 0.0005\n", - "Epoch [438/500], Loss: 0.0000\n", - "Epoch [439/500], Loss: 0.0003\n", - "Epoch [440/500], Loss: 0.0002\n", - "Epoch [441/500], Loss: 0.0005\n", - "Epoch [442/500], Loss: 0.0000\n", - "Epoch [443/500], Loss: 0.0013\n", - "Epoch [444/500], Loss: 0.0035\n", - "Epoch [445/500], Loss: 0.0003\n", - "Epoch [446/500], Loss: 0.0001\n", - "Epoch [447/500], Loss: 0.0005\n", - "Epoch [448/500], Loss: 0.0001\n", - "Epoch [449/500], Loss: 0.0025\n", - "Epoch [450/500], Loss: 0.0020\n", - "Epoch [451/500], Loss: 0.0002\n", - "Epoch [452/500], Loss: 0.0013\n", - "Epoch [453/500], Loss: 0.0000\n", - "Epoch [454/500], Loss: 0.0000\n", - "Epoch [455/500], Loss: 0.0003\n", - "Epoch [456/500], Loss: 0.0000\n", - "Epoch [457/500], Loss: 0.0012\n", - "Epoch [458/500], Loss: 0.0001\n", - "Epoch [459/500], Loss: 0.0006\n", - "Epoch [460/500], Loss: 0.0004\n", - "Epoch [461/500], Loss: 0.0000\n", - "Epoch [462/500], Loss: 0.0021\n", - "Epoch [463/500], Loss: 0.0003\n", - "Epoch [464/500], Loss: 0.0002\n", - "Epoch [465/500], Loss: 0.0015\n", - "Epoch [466/500], Loss: 0.0003\n", - "Epoch [467/500], Loss: 0.0018\n", - "Epoch [468/500], Loss: 0.0020\n", - "Epoch [469/500], Loss: 0.0002\n", - "Epoch [470/500], Loss: 0.0060\n", - "Epoch [471/500], Loss: 0.0005\n", - "Epoch [472/500], Loss: 0.0000\n", - "Epoch [473/500], Loss: 0.0050\n", - "Epoch [474/500], Loss: 0.0009\n", - "Epoch [475/500], Loss: 0.0001\n", - "Epoch [476/500], Loss: 0.0003\n", - "Epoch [477/500], Loss: 0.0002\n", - "Epoch [478/500], Loss: 0.0001\n", - "Epoch [479/500], Loss: 0.0005\n", - "Epoch [480/500], Loss: 0.0000\n", - "Epoch [481/500], Loss: 0.0004\n", - "Epoch [482/500], Loss: 0.0012\n", - "Epoch [483/500], Loss: 0.0001\n", - "Epoch [484/500], Loss: 0.0031\n", - "Epoch [485/500], Loss: 0.0006\n", - "Epoch [486/500], Loss: 0.0003\n", - "Epoch [487/500], Loss: 0.0022\n", - "Epoch [488/500], Loss: 0.0019\n", - "Epoch [489/500], Loss: 0.0013\n", - "Epoch [490/500], Loss: 0.0000\n", - "Epoch [491/500], Loss: 0.0001\n", - "Epoch [492/500], Loss: 0.0022\n", - "Epoch [493/500], Loss: 0.0008\n", - "Epoch [494/500], Loss: 0.0012\n", - "Epoch [495/500], Loss: 0.0057\n", - "Epoch [496/500], Loss: 0.0047\n", - "Epoch [497/500], Loss: 0.0005\n", - "Epoch [498/500], Loss: 0.0001\n", - "Epoch [499/500], Loss: 0.0000\n", - "Epoch [500/500], Loss: 0.0000\n" + "Epoch [15/500], Loss: 0.0000\n", + "Epoch [16/500], Loss: 0.0001\n", + "Epoch [17/500], Loss: 0.0005\n", + "Epoch [18/500], Loss: 0.0084\n", + "Epoch [19/500], Loss: 0.0000\n", + "Epoch [20/500], Loss: 0.0011\n", + "Epoch [21/500], Loss: 0.0002\n", + "Epoch [22/500], Loss: 0.0001\n", + "Epoch [23/500], Loss: 0.0000\n", + "Epoch [24/500], Loss: 0.0000\n", + "Epoch [25/500], Loss: 0.0000\n", + "Epoch [26/500], Loss: 0.0000\n", + "Epoch [27/500], Loss: 0.0000\n", + "Epoch [28/500], Loss: 0.0000\n", + "Epoch [29/500], Loss: 0.0000\n", + "Epoch [30/500], Loss: 0.0000\n", + "Epoch [31/500], Loss: 0.0000\n", + "Epoch [32/500], Loss: 0.0000\n", + "Epoch [33/500], Loss: 0.0001\n", + "Epoch [34/500], Loss: 0.0001\n", + "Epoch [35/500], Loss: 0.0001\n", + "Epoch [36/500], Loss: 0.0001\n", + "Epoch [37/500], Loss: 0.0001\n", + "Epoch [38/500], Loss: 0.0001\n", + "Epoch [39/500], Loss: 0.0001\n", + "Epoch [40/500], Loss: 0.0002\n", + "Epoch [41/500], Loss: 0.0002\n", + "Epoch [42/500], Loss: 0.0002\n", + "Epoch [43/500], Loss: 0.0002\n", + "Epoch [44/500], Loss: 0.0003\n", + "Epoch [45/500], Loss: 0.0003\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[4], line 14\u001b[0m\n\u001b[0;32m 11\u001b[0m labels \u001b[38;5;241m=\u001b[39m labels\u001b[38;5;241m.\u001b[39munsqueeze(\u001b[38;5;241m0\u001b[39m) \u001b[38;5;66;03m# Add batch dimension\u001b[39;00m\n\u001b[0;32m 13\u001b[0m \u001b[38;5;66;03m# Forward pass\u001b[39;00m\n\u001b[1;32m---> 14\u001b[0m outputs \u001b[38;5;241m=\u001b[39m \u001b[43mmodel\u001b[49m\u001b[43m(\u001b[49m\u001b[43msequences\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 15\u001b[0m loss \u001b[38;5;241m=\u001b[39m criterion(outputs, labels)\n\u001b[0;32m 17\u001b[0m \u001b[38;5;66;03m# Backward pass and optimization\u001b[39;00m\n", + "File \u001b[1;32mc:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\torch\\nn\\modules\\module.py:1739\u001b[0m, in \u001b[0;36mModule._wrapped_call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1737\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_compiled_call_impl(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs) \u001b[38;5;66;03m# type: ignore[misc]\u001b[39;00m\n\u001b[0;32m 1738\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m-> 1739\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_impl\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[1;32mc:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\torch\\nn\\modules\\module.py:1750\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[1;34m(self, *args, **kwargs)\u001b[0m\n\u001b[0;32m 1745\u001b[0m \u001b[38;5;66;03m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[0;32m 1746\u001b[0m \u001b[38;5;66;03m# this function, and just call forward.\u001b[39;00m\n\u001b[0;32m 1747\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_forward_pre_hooks\n\u001b[0;32m 1748\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_backward_pre_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_backward_hooks\n\u001b[0;32m 1749\u001b[0m \u001b[38;5;129;01mor\u001b[39;00m _global_forward_hooks \u001b[38;5;129;01mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[1;32m-> 1750\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mforward_call\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1752\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 1753\u001b[0m called_always_called_hooks \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mset\u001b[39m()\n", + "Cell \u001b[1;32mIn[3], line 24\u001b[0m, in \u001b[0;36mRNNModel.forward\u001b[1;34m(self, x)\u001b[0m\n\u001b[0;32m 22\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m t \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(seq_len):\n\u001b[0;32m 23\u001b[0m x_t \u001b[38;5;241m=\u001b[39m x[:, t, :]\n\u001b[1;32m---> 24\u001b[0m h_t \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtanh(x_t \u001b[38;5;241m@\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mW_ih \u001b[38;5;241m+\u001b[39m h_t \u001b[38;5;241m@\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mW_hh \u001b[38;5;241m+\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mb_h\u001b[49m)\n\u001b[0;32m 26\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_layer(h_t)\n\u001b[0;32m 27\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m output\n", + "File \u001b[1;32mc:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\torch\\nn\\modules\\module.py:1915\u001b[0m, in \u001b[0;36mModule.__getattr__\u001b[1;34m(self, name)\u001b[0m\n\u001b[0;32m 1910\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_backward_pre_hooks \u001b[38;5;241m=\u001b[39m OrderedDict()\n\u001b[0;32m 1912\u001b[0m \u001b[38;5;66;03m# It is crucial that the return type is not annotated as `Any`, otherwise type checking\u001b[39;00m\n\u001b[0;32m 1913\u001b[0m \u001b[38;5;66;03m# on `torch.nn.Module` and all its subclasses is largely disabled as a result. See:\u001b[39;00m\n\u001b[0;32m 1914\u001b[0m \u001b[38;5;66;03m# https://github.com/pytorch/pytorch/pull/115074\u001b[39;00m\n\u001b[1;32m-> 1915\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[38;5;21m__getattr__\u001b[39m(\u001b[38;5;28mself\u001b[39m, name: \u001b[38;5;28mstr\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Union[Tensor, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mModule\u001b[39m\u001b[38;5;124m\"\u001b[39m]:\n\u001b[0;32m 1916\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_parameters\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__dict__\u001b[39m:\n\u001b[0;32m 1917\u001b[0m _parameters \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__dict__\u001b[39m[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m_parameters\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", + "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], @@ -623,7 +198,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -649,7 +224,7 @@ ], "metadata": { "kernelspec": { - "display_name": ".venv", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -663,7 +238,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.4" + "version": "3.12.9" } }, "nbformat": 4, From 5bd47c5165ffe7b4e6985a08f23dcd57cb70e6bd Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 25 May 2025 15:43:59 -0700 Subject: [PATCH 27/40] Updated Question Set --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4c9e69d..5325942 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) 8. Implement AlexNet from scratch 9. Build a Dense Retrieval System using PyTorch +10. Implement KNN from scratch in PyTorch ** Finding these too easy? Try implementing from scratch in empty ntbk** @@ -66,14 +67,17 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 8. [Work with Sparse Tensors] 9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) 10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai_SOLN.ipynb) - +11. Linear Probe on CLIP Features +12. Add Cross Modal Embedding Visualization to CLIP (t-SNE/UMAP) +13. Implement a Vision Transformer +14. Implement a Variational Autoencoder ## LLM Set **An all new set of questions to help you understand and implement Large Language Models from scratch.** 1. Implement KL Divergence Loss -2. Implement RMS ~~Norm~~ +2. Implement RMS Norm 3. [Implement Byte Pair Encoding from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3.ipynb) 4. [Create an embeddings out of an LLM](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) 5. Implement Predictive Prefill with Speculative Decoding From 9283b67eb8ddbdbd27834b784bc4d011a0c37114 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sun, 25 May 2025 19:58:36 -0700 Subject: [PATCH 28/40] New Ordering in README --- README.md | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5325942..efffb42 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st ## Question Set -### ๐ŸŸขEasy +### ๐Ÿ”ตBasic +Mostly for beginners to get started with PyTorch. + 1. [Implement linear regression](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression_SOLN.ipynb) 2. [Write a custom Dataset and Dataloader to load from a CSV file](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset_SOLN.ipynb) 3. [Write a custom activation function (Simple)](https://github.com/Exorust/TorchLeet/torch/easy/e3/custom-activation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e3/custom-activation_SOLN.ipynb) @@ -40,32 +42,41 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard_SOLN.ipynb) 7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model_SOLN.ipynb) 10. Implement Softmax function from scratch - - -### ๐ŸŸกMedium + +### ๐ŸŸขEasy +Recommended for those who have a basic understanding of PyTorch and want to practice their skills. 1. [Implement an LSTM](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) 2. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) -3. [Implement parameter initialization for a CNN]() [(Solution)]() 4. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) 5. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) 6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) 7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) -8. Implement AlexNet from scratch -9. Build a Dense Retrieval System using PyTorch -10. Implement KNN from scratch in PyTorch +6. [Quantize your language model](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model_SOLN.ipynb) +9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) + +### ๐ŸŸกMedium +These problems are designed to challenge your understanding of PyTorch and deep learning concepts. They require you to implement things from scratch or apply advanced techniques. +1. [Implement parameter initialization for a CNN]() [(Solution)]() +2. Implement a CNN from Scratch +3. Implement an RNN from Scratch +4. Implement an LSTM from Scratch +6. Implement AlexNet from scratch +7. Build a Dense Retrieval System using PyTorch +8. Implement KNN from scratch in PyTorch -** Finding these too easy? Try implementing from scratch in empty ntbk** +** Finding these too easy? Try implementing in an empty ntbk** ### ๐Ÿ”ดHard +These problems are for advanced users who want to push their PyTorch skills to the limit. They involve complex architectures, custom layers, and advanced techniques. 1. [Write a custom Autograd function for activation (SILU)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function_SOLN.ipynb) 2. Write a Neural Style Transfer -3. [Write a Transformer](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer_SOLN.ipynb) -4. [Write a GAN](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN_SOLN.ipynb) -5. [Write Sequence-to-Sequence with Attention](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb) -6. [Quantize your language model](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model_SOLN.ipynb) -7. [Enable distributed training in pytorch (DistributedDataParallel)] -8. [Work with Sparse Tensors] -9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) +3. Build a Graph Neural Network (GNN) from scratch +4. Build a Graph Convolutional Network (GCN) from scratch +5. [Write a Transformer](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer_SOLN.ipynb) +6. [Write a GAN](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN_SOLN.ipynb) +7. [Write Sequence-to-Sequence with Attention](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb) +8. [Enable distributed training in pytorch (DistributedDataParallel)] +9. [Work with Sparse Tensors] 10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai_SOLN.ipynb) 11. Linear Probe on CLIP Features 12. Add Cross Modal Embedding Visualization to CLIP (t-SNE/UMAP) @@ -89,12 +100,13 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st 11. [Implement ROPE Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8.ipynb) 12. [Implement SmolLM from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12.ipynb) 13. Implement Quantization of Models - a. Types of Quantization + 1. GPTQ 14. Implement Beam Search atop LLM for decoding 15. Implement Top K Sampling atop LLM for decoding 16. Implement Top p Sampling atop LLM for decoding 17. Implement Temperature Sampling atop LLM for decoding 18. Implement LoRA on a layer of an LLM + 1. QLoRA? 19. Mix two models to create a mixture of Experts 20. Apply SFT on SmolLM 21. Apply RLHF on SmolLM From ea57d47a17dd9dd79c58eae579ca3e5e1b3f2651 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 09:55:09 -0700 Subject: [PATCH 29/40] Refactoring --- README.md | 15 +- .../e5 => basic/custom-DNN}/custon-DNN.ipynb | 0 .../custom-DNN}/custon-DNN_SOLN.ipynb | 0 .../custom-activation.ipynb | 0 .../custom-activation_SOLN.ipynb | 0 .../custom-dataset}/custom-dataset.ipynb | 0 .../custom-dataset}/custom-dataset_SOLN.ipynb | 0 .../e2 => basic/custom-dataset}/data.csv | 0 .../custom-loss}/custom-loss.ipynb | 0 .../custom-loss}/custom-loss_SOLN.ipynb | 0 .../lin-regression}/lin-regression.ipynb | 0 .../lin-regression}/lin-regression_SOLN.ipynb | 0 .../e7 => basic/save-model}/save_model.ipynb | 0 .../save-model}/save_model_SOLN.ipynb | 0 .../tensorboard}/tensorboard.ipynb | 0 .../tensorboard}/tensorboard_SOLN.ipynb | 0 .../augmentation}/augmentation.ipynb | 0 .../augmentation}/augmentation_SOLN.ipynb | 0 .../m7 => easy/autoencoder}/autoencoder.ipynb | 0 .../autoencoder}/autoencoder_SOLN.ipynb | 0 .../{medium/m6 => easy/benchmark}/bench.ipynb | 0 .../m6 => easy/benchmark}/bench_SOLN.ipynb | 0 torch/{medium/m2 => easy/cnn}/CNN.ipynb | 0 torch/{medium/m2 => easy/cnn}/CNN_SOLN.ipynb | 0 .../{hard/h9 => easy/cuda-amp}/cuda-amp.ipynb | 0 .../h9 => easy/cuda-amp}/cuda-amp_SOLN.ipynb | 0 .../quantize-language-model.ipynb | 0 .../quantize-language-model_SOLN.ipynb | 0 torch/{medium/m4 => easy/rnn}/RNN.ipynb | 0 torch/{medium/m4 => easy/rnn}/RNN_SOLN.ipynb | 0 torch/hard/{h4 => GAN}/GAN.ipynb | 0 torch/hard/{h4 => GAN}/GAN_SOLN.ipynb | 0 .../custom-autgrad-function.ipynb | 0 .../custom-autgrad-function_SOLN.ipynb | 0 .../seq-to-seq-with-Attention.ipynb | 0 .../seq-to-seq-with-Attention_SOLN.ipynb | 0 .../{h3 => transformer}/transformer.ipynb | 0 .../transformer_SOLN.ipynb | 0 torch/hard/{h10 => xai}/xai.ipynb | 0 torch/hard/{h10 => xai}/xai_SOLN.ipynb | 0 .../CNN_ParamInit.ipynb | 0 .../CNN_ParamInit_SOLN.ipynb | 0 torch/medium/cnn/CNN.ipynb | 203 +++++++++++++++++ torch/medium/cnn/CNN_SOLN.ipynb | 213 ++++++++++++++++++ torch/medium/{m1 => lstm}/LSTM.ipynb | 0 torch/medium/{m1 => lstm}/LSTM_SOLN.ipynb | 0 46 files changed, 423 insertions(+), 8 deletions(-) rename torch/{easy/e5 => basic/custom-DNN}/custon-DNN.ipynb (100%) rename torch/{easy/e5 => basic/custom-DNN}/custon-DNN_SOLN.ipynb (100%) rename torch/{easy/e3 => basic/custom-activation}/custom-activation.ipynb (100%) rename torch/{easy/e3 => basic/custom-activation}/custom-activation_SOLN.ipynb (100%) rename torch/{easy/e2 => basic/custom-dataset}/custom-dataset.ipynb (100%) rename torch/{easy/e2 => basic/custom-dataset}/custom-dataset_SOLN.ipynb (100%) rename torch/{easy/e2 => basic/custom-dataset}/data.csv (100%) rename torch/{easy/e4 => basic/custom-loss}/custom-loss.ipynb (100%) rename torch/{easy/e4 => basic/custom-loss}/custom-loss_SOLN.ipynb (100%) rename torch/{easy/e1 => basic/lin-regression}/lin-regression.ipynb (100%) rename torch/{easy/e1 => basic/lin-regression}/lin-regression_SOLN.ipynb (100%) rename torch/{easy/e7 => basic/save-model}/save_model.ipynb (100%) rename torch/{easy/e7 => basic/save-model}/save_model_SOLN.ipynb (100%) rename torch/{easy/e6 => basic/tensorboard}/tensorboard.ipynb (100%) rename torch/{easy/e6 => basic/tensorboard}/tensorboard_SOLN.ipynb (100%) rename torch/{medium/m5 => easy/augmentation}/augmentation.ipynb (100%) rename torch/{medium/m5 => easy/augmentation}/augmentation_SOLN.ipynb (100%) rename torch/{medium/m7 => easy/autoencoder}/autoencoder.ipynb (100%) rename torch/{medium/m7 => easy/autoencoder}/autoencoder_SOLN.ipynb (100%) rename torch/{medium/m6 => easy/benchmark}/bench.ipynb (100%) rename torch/{medium/m6 => easy/benchmark}/bench_SOLN.ipynb (100%) rename torch/{medium/m2 => easy/cnn}/CNN.ipynb (100%) rename torch/{medium/m2 => easy/cnn}/CNN_SOLN.ipynb (100%) rename torch/{hard/h9 => easy/cuda-amp}/cuda-amp.ipynb (100%) rename torch/{hard/h9 => easy/cuda-amp}/cuda-amp_SOLN.ipynb (100%) rename torch/{hard/h6 => easy/quantize-lm}/quantize-language-model.ipynb (100%) rename torch/{hard/h6 => easy/quantize-lm}/quantize-language-model_SOLN.ipynb (100%) rename torch/{medium/m4 => easy/rnn}/RNN.ipynb (100%) rename torch/{medium/m4 => easy/rnn}/RNN_SOLN.ipynb (100%) rename torch/hard/{h4 => GAN}/GAN.ipynb (100%) rename torch/hard/{h4 => GAN}/GAN_SOLN.ipynb (100%) rename torch/hard/{h1 => custom-autograd}/custom-autgrad-function.ipynb (100%) rename torch/hard/{h1 => custom-autograd}/custom-autgrad-function_SOLN.ipynb (100%) rename torch/hard/{h5 => seq-seq}/seq-to-seq-with-Attention.ipynb (100%) rename torch/hard/{h5 => seq-seq}/seq-to-seq-with-Attention_SOLN.ipynb (100%) rename torch/hard/{h3 => transformer}/transformer.ipynb (100%) rename torch/hard/{h3 => transformer}/transformer_SOLN.ipynb (100%) rename torch/hard/{h10 => xai}/xai.ipynb (100%) rename torch/hard/{h10 => xai}/xai_SOLN.ipynb (100%) rename torch/medium/{m3 => cnn-param-init}/CNN_ParamInit.ipynb (100%) rename torch/medium/{m3 => cnn-param-init}/CNN_ParamInit_SOLN.ipynb (100%) create mode 100644 torch/medium/cnn/CNN.ipynb create mode 100644 torch/medium/cnn/CNN_SOLN.ipynb rename torch/medium/{m1 => lstm}/LSTM.ipynb (100%) rename torch/medium/{m1 => lstm}/LSTM_SOLN.ipynb (100%) diff --git a/README.md b/README.md index efffb42..daaaac3 100644 --- a/README.md +++ b/README.md @@ -45,21 +45,20 @@ Mostly for beginners to get started with PyTorch. ### ๐ŸŸขEasy Recommended for those who have a basic understanding of PyTorch and want to practice their skills. -1. [Implement an LSTM](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) -2. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) -4. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) -5. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) -6. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) -7. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) +1. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) +2. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) +3. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) +4. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) +5. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) 6. [Quantize your language model](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model_SOLN.ipynb) -9. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) +7. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) ### ๐ŸŸกMedium These problems are designed to challenge your understanding of PyTorch and deep learning concepts. They require you to implement things from scratch or apply advanced techniques. 1. [Implement parameter initialization for a CNN]() [(Solution)]() 2. Implement a CNN from Scratch 3. Implement an RNN from Scratch -4. Implement an LSTM from Scratch +4. [Implement an LSTM from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) 6. Implement AlexNet from scratch 7. Build a Dense Retrieval System using PyTorch 8. Implement KNN from scratch in PyTorch diff --git a/torch/easy/e5/custon-DNN.ipynb b/torch/basic/custom-DNN/custon-DNN.ipynb similarity index 100% rename from torch/easy/e5/custon-DNN.ipynb rename to torch/basic/custom-DNN/custon-DNN.ipynb diff --git a/torch/easy/e5/custon-DNN_SOLN.ipynb b/torch/basic/custom-DNN/custon-DNN_SOLN.ipynb similarity index 100% rename from torch/easy/e5/custon-DNN_SOLN.ipynb rename to torch/basic/custom-DNN/custon-DNN_SOLN.ipynb diff --git a/torch/easy/e3/custom-activation.ipynb b/torch/basic/custom-activation/custom-activation.ipynb similarity index 100% rename from torch/easy/e3/custom-activation.ipynb rename to torch/basic/custom-activation/custom-activation.ipynb diff --git a/torch/easy/e3/custom-activation_SOLN.ipynb b/torch/basic/custom-activation/custom-activation_SOLN.ipynb similarity index 100% rename from torch/easy/e3/custom-activation_SOLN.ipynb rename to torch/basic/custom-activation/custom-activation_SOLN.ipynb diff --git a/torch/easy/e2/custom-dataset.ipynb b/torch/basic/custom-dataset/custom-dataset.ipynb similarity index 100% rename from torch/easy/e2/custom-dataset.ipynb rename to torch/basic/custom-dataset/custom-dataset.ipynb diff --git a/torch/easy/e2/custom-dataset_SOLN.ipynb b/torch/basic/custom-dataset/custom-dataset_SOLN.ipynb similarity index 100% rename from torch/easy/e2/custom-dataset_SOLN.ipynb rename to torch/basic/custom-dataset/custom-dataset_SOLN.ipynb diff --git a/torch/easy/e2/data.csv b/torch/basic/custom-dataset/data.csv similarity index 100% rename from torch/easy/e2/data.csv rename to torch/basic/custom-dataset/data.csv diff --git a/torch/easy/e4/custom-loss.ipynb b/torch/basic/custom-loss/custom-loss.ipynb similarity index 100% rename from torch/easy/e4/custom-loss.ipynb rename to torch/basic/custom-loss/custom-loss.ipynb diff --git a/torch/easy/e4/custom-loss_SOLN.ipynb b/torch/basic/custom-loss/custom-loss_SOLN.ipynb similarity index 100% rename from torch/easy/e4/custom-loss_SOLN.ipynb rename to torch/basic/custom-loss/custom-loss_SOLN.ipynb diff --git a/torch/easy/e1/lin-regression.ipynb b/torch/basic/lin-regression/lin-regression.ipynb similarity index 100% rename from torch/easy/e1/lin-regression.ipynb rename to torch/basic/lin-regression/lin-regression.ipynb diff --git a/torch/easy/e1/lin-regression_SOLN.ipynb b/torch/basic/lin-regression/lin-regression_SOLN.ipynb similarity index 100% rename from torch/easy/e1/lin-regression_SOLN.ipynb rename to torch/basic/lin-regression/lin-regression_SOLN.ipynb diff --git a/torch/easy/e7/save_model.ipynb b/torch/basic/save-model/save_model.ipynb similarity index 100% rename from torch/easy/e7/save_model.ipynb rename to torch/basic/save-model/save_model.ipynb diff --git a/torch/easy/e7/save_model_SOLN.ipynb b/torch/basic/save-model/save_model_SOLN.ipynb similarity index 100% rename from torch/easy/e7/save_model_SOLN.ipynb rename to torch/basic/save-model/save_model_SOLN.ipynb diff --git a/torch/easy/e6/tensorboard.ipynb b/torch/basic/tensorboard/tensorboard.ipynb similarity index 100% rename from torch/easy/e6/tensorboard.ipynb rename to torch/basic/tensorboard/tensorboard.ipynb diff --git a/torch/easy/e6/tensorboard_SOLN.ipynb b/torch/basic/tensorboard/tensorboard_SOLN.ipynb similarity index 100% rename from torch/easy/e6/tensorboard_SOLN.ipynb rename to torch/basic/tensorboard/tensorboard_SOLN.ipynb diff --git a/torch/medium/m5/augmentation.ipynb b/torch/easy/augmentation/augmentation.ipynb similarity index 100% rename from torch/medium/m5/augmentation.ipynb rename to torch/easy/augmentation/augmentation.ipynb diff --git a/torch/medium/m5/augmentation_SOLN.ipynb b/torch/easy/augmentation/augmentation_SOLN.ipynb similarity index 100% rename from torch/medium/m5/augmentation_SOLN.ipynb rename to torch/easy/augmentation/augmentation_SOLN.ipynb diff --git a/torch/medium/m7/autoencoder.ipynb b/torch/easy/autoencoder/autoencoder.ipynb similarity index 100% rename from torch/medium/m7/autoencoder.ipynb rename to torch/easy/autoencoder/autoencoder.ipynb diff --git a/torch/medium/m7/autoencoder_SOLN.ipynb b/torch/easy/autoencoder/autoencoder_SOLN.ipynb similarity index 100% rename from torch/medium/m7/autoencoder_SOLN.ipynb rename to torch/easy/autoencoder/autoencoder_SOLN.ipynb diff --git a/torch/medium/m6/bench.ipynb b/torch/easy/benchmark/bench.ipynb similarity index 100% rename from torch/medium/m6/bench.ipynb rename to torch/easy/benchmark/bench.ipynb diff --git a/torch/medium/m6/bench_SOLN.ipynb b/torch/easy/benchmark/bench_SOLN.ipynb similarity index 100% rename from torch/medium/m6/bench_SOLN.ipynb rename to torch/easy/benchmark/bench_SOLN.ipynb diff --git a/torch/medium/m2/CNN.ipynb b/torch/easy/cnn/CNN.ipynb similarity index 100% rename from torch/medium/m2/CNN.ipynb rename to torch/easy/cnn/CNN.ipynb diff --git a/torch/medium/m2/CNN_SOLN.ipynb b/torch/easy/cnn/CNN_SOLN.ipynb similarity index 100% rename from torch/medium/m2/CNN_SOLN.ipynb rename to torch/easy/cnn/CNN_SOLN.ipynb diff --git a/torch/hard/h9/cuda-amp.ipynb b/torch/easy/cuda-amp/cuda-amp.ipynb similarity index 100% rename from torch/hard/h9/cuda-amp.ipynb rename to torch/easy/cuda-amp/cuda-amp.ipynb diff --git a/torch/hard/h9/cuda-amp_SOLN.ipynb b/torch/easy/cuda-amp/cuda-amp_SOLN.ipynb similarity index 100% rename from torch/hard/h9/cuda-amp_SOLN.ipynb rename to torch/easy/cuda-amp/cuda-amp_SOLN.ipynb diff --git a/torch/hard/h6/quantize-language-model.ipynb b/torch/easy/quantize-lm/quantize-language-model.ipynb similarity index 100% rename from torch/hard/h6/quantize-language-model.ipynb rename to torch/easy/quantize-lm/quantize-language-model.ipynb diff --git a/torch/hard/h6/quantize-language-model_SOLN.ipynb b/torch/easy/quantize-lm/quantize-language-model_SOLN.ipynb similarity index 100% rename from torch/hard/h6/quantize-language-model_SOLN.ipynb rename to torch/easy/quantize-lm/quantize-language-model_SOLN.ipynb diff --git a/torch/medium/m4/RNN.ipynb b/torch/easy/rnn/RNN.ipynb similarity index 100% rename from torch/medium/m4/RNN.ipynb rename to torch/easy/rnn/RNN.ipynb diff --git a/torch/medium/m4/RNN_SOLN.ipynb b/torch/easy/rnn/RNN_SOLN.ipynb similarity index 100% rename from torch/medium/m4/RNN_SOLN.ipynb rename to torch/easy/rnn/RNN_SOLN.ipynb diff --git a/torch/hard/h4/GAN.ipynb b/torch/hard/GAN/GAN.ipynb similarity index 100% rename from torch/hard/h4/GAN.ipynb rename to torch/hard/GAN/GAN.ipynb diff --git a/torch/hard/h4/GAN_SOLN.ipynb b/torch/hard/GAN/GAN_SOLN.ipynb similarity index 100% rename from torch/hard/h4/GAN_SOLN.ipynb rename to torch/hard/GAN/GAN_SOLN.ipynb diff --git a/torch/hard/h1/custom-autgrad-function.ipynb b/torch/hard/custom-autograd/custom-autgrad-function.ipynb similarity index 100% rename from torch/hard/h1/custom-autgrad-function.ipynb rename to torch/hard/custom-autograd/custom-autgrad-function.ipynb diff --git a/torch/hard/h1/custom-autgrad-function_SOLN.ipynb b/torch/hard/custom-autograd/custom-autgrad-function_SOLN.ipynb similarity index 100% rename from torch/hard/h1/custom-autgrad-function_SOLN.ipynb rename to torch/hard/custom-autograd/custom-autgrad-function_SOLN.ipynb diff --git a/torch/hard/h5/seq-to-seq-with-Attention.ipynb b/torch/hard/seq-seq/seq-to-seq-with-Attention.ipynb similarity index 100% rename from torch/hard/h5/seq-to-seq-with-Attention.ipynb rename to torch/hard/seq-seq/seq-to-seq-with-Attention.ipynb diff --git a/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb b/torch/hard/seq-seq/seq-to-seq-with-Attention_SOLN.ipynb similarity index 100% rename from torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb rename to torch/hard/seq-seq/seq-to-seq-with-Attention_SOLN.ipynb diff --git a/torch/hard/h3/transformer.ipynb b/torch/hard/transformer/transformer.ipynb similarity index 100% rename from torch/hard/h3/transformer.ipynb rename to torch/hard/transformer/transformer.ipynb diff --git a/torch/hard/h3/transformer_SOLN.ipynb b/torch/hard/transformer/transformer_SOLN.ipynb similarity index 100% rename from torch/hard/h3/transformer_SOLN.ipynb rename to torch/hard/transformer/transformer_SOLN.ipynb diff --git a/torch/hard/h10/xai.ipynb b/torch/hard/xai/xai.ipynb similarity index 100% rename from torch/hard/h10/xai.ipynb rename to torch/hard/xai/xai.ipynb diff --git a/torch/hard/h10/xai_SOLN.ipynb b/torch/hard/xai/xai_SOLN.ipynb similarity index 100% rename from torch/hard/h10/xai_SOLN.ipynb rename to torch/hard/xai/xai_SOLN.ipynb diff --git a/torch/medium/m3/CNN_ParamInit.ipynb b/torch/medium/cnn-param-init/CNN_ParamInit.ipynb similarity index 100% rename from torch/medium/m3/CNN_ParamInit.ipynb rename to torch/medium/cnn-param-init/CNN_ParamInit.ipynb diff --git a/torch/medium/m3/CNN_ParamInit_SOLN.ipynb b/torch/medium/cnn-param-init/CNN_ParamInit_SOLN.ipynb similarity index 100% rename from torch/medium/m3/CNN_ParamInit_SOLN.ipynb rename to torch/medium/cnn-param-init/CNN_ParamInit_SOLN.ipynb diff --git a/torch/medium/cnn/CNN.ipynb b/torch/medium/cnn/CNN.ipynb new file mode 100644 index 0000000..ccab9f0 --- /dev/null +++ b/torch/medium/cnn/CNN.ipynb @@ -0,0 +1,203 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Problem: Implement a CNN for CIFAR-10 in PyTorch\n", + "\n", + "### Problem Statement\n", + "You are tasked with implementing a **Convolutional Neural Network (CNN)** for image classification on the **CIFAR-10** dataset using PyTorch. The model should contain convolutional layers for feature extraction, pooling layers for downsampling, and fully connected layers for classification. Your goal is to complete the CNN model by defining the necessary layers and implementing the forward pass.\n", + "\n", + "### Requirements\n", + "1. **Define the CNN Model**:\n", + " - Add **convolutional layers** for feature extraction.\n", + " - Add **pooling layers** to reduce the spatial dimensions.\n", + " - Add **fully connected layers** to output class predictions.\n", + " - The model should be capable of processing input images of size `(32x32x3)` as in the CIFAR-10 dataset.\n", + "\n", + "### Constraints\n", + "- The CNN should be designed with multiple convolutional and pooling layers followed by fully connected layers.\n", + "- Ensure the model is compatible with the CIFAR-10 dataset, which contains 10 classes.\n", + "\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Add the convolutional (conv1, conv2), pooling (pool), and fully connected layers (fc1, fc2) in CNNModel.__init__.\n", + "
\n", + " Implement the forward pass to process inputs through these layers.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torchvision\n", + "import torchvision.transforms as transforms" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\\cifar-10-python.tar.gz\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8dcf56f0d6f941e48bd710768cad07e5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/170498071 [00:00\n", + " ๐Ÿ’ก Hint\n", + " Add the convolutional (conv1, conv2), pooling (pool), and fully connected layers (fc1, fc2) in CNNModel.__init__.\n", + "
\n", + " Implement the forward pass to process inputs through these layers.\n", + "
" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torchvision\n", + "import torchvision.transforms as transforms" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\\cifar-10-python.tar.gz\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8dcf56f0d6f941e48bd710768cad07e5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/170498071 [00:00 Date: Mon, 26 May 2025 10:00:54 -0700 Subject: [PATCH 30/40] Adding CNN Scratch --- README.md | 13 +- .../CNN_scratch.ipynb} | 58 +++- .../medium/cnn-scratch/CNN_scratch_SOLN.ipynb | 290 ++++++++++++++++++ torch/medium/cnn/CNN.ipynb | 203 ------------ 4 files changed, 338 insertions(+), 226 deletions(-) rename torch/medium/{cnn/CNN_SOLN.ipynb => cnn-scratch/CNN_scratch.ipynb} (70%) create mode 100644 torch/medium/cnn-scratch/CNN_scratch_SOLN.ipynb delete mode 100644 torch/medium/cnn/CNN.ipynb diff --git a/README.md b/README.md index daaaac3..bda2b2b 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Mostly for beginners to get started with PyTorch. ### ๐ŸŸขEasy Recommended for those who have a basic understanding of PyTorch and want to practice their skills. 1. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) -2. [Implement an RNN](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) +2. [Implement an RNN from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) 3. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) 4. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) 5. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) @@ -56,12 +56,11 @@ Recommended for those who have a basic understanding of PyTorch and want to prac ### ๐ŸŸกMedium These problems are designed to challenge your understanding of PyTorch and deep learning concepts. They require you to implement things from scratch or apply advanced techniques. 1. [Implement parameter initialization for a CNN]() [(Solution)]() -2. Implement a CNN from Scratch -3. Implement an RNN from Scratch -4. [Implement an LSTM from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) -6. Implement AlexNet from scratch -7. Build a Dense Retrieval System using PyTorch -8. Implement KNN from scratch in PyTorch +2. [Implement a CNN from Scratch]() +3. [Implement an LSTM from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) +4. Implement AlexNet from scratch +5. Build a Dense Retrieval System using PyTorch +6. Implement KNN from scratch in PyTorch ** Finding these too easy? Try implementing in an empty ntbk** diff --git a/torch/medium/cnn/CNN_SOLN.ipynb b/torch/medium/cnn-scratch/CNN_scratch.ipynb similarity index 70% rename from torch/medium/cnn/CNN_SOLN.ipynb rename to torch/medium/cnn-scratch/CNN_scratch.ipynb index 253eb75..42efebb 100644 --- a/torch/medium/cnn/CNN_SOLN.ipynb +++ b/torch/medium/cnn-scratch/CNN_scratch.ipynb @@ -4,34 +4,38 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Problem: Implement a CNN for CIFAR-10\n", + "# Problem: Implement a CNN for CIFAR-10 (With Custom Layers)\n", "\n", "### Problem Statement\n", - "You are tasked with implementing a **Convolutional Neural Network (CNN)** for image classification on the **CIFAR-10** dataset using PyTorch. The model should contain convolutional layers for feature extraction, pooling layers for downsampling, and fully connected layers for classification. Your goal is to complete the CNN model by defining the necessary layers and implementing the forward pass.\n", + "You are tasked with implementing a **Convolutional Neural Network (CNN)** for image classification on the **CIFAR-10** dataset using PyTorch. However, instead of using PyTorch's built-in `nn.Conv2d` and `nn.MaxPool2d`, you must implement these layers **from scratch** using `nn.Module`. Your model will include convolutional layers for feature extraction, pooling layers for downsampling, and fully connected layers for classification.\n", "\n", "### Requirements\n", - "1. **Define the CNN Model**:\n", - " - Add **convolutional layers** for feature extraction.\n", - " - Add **pooling layers** to reduce the spatial dimensions.\n", - " - Add **fully connected layers** to output class predictions.\n", - " - The model should be capable of processing input images of size `(32x32x3)` as in the CIFAR-10 dataset.\n", + "1. **Implement Custom Layers**:\n", + " - Create a custom `Conv2dCustom` class that mimics the behavior of `nn.Conv2d`.\n", + " - Create a custom `MaxPool2dCustom` class that mimics the behavior of `nn.MaxPool2d`.\n", "\n", - "### Constraints\n", - "- The CNN should be designed with multiple convolutional and pooling layers followed by fully connected layers.\n", - "- Ensure the model is compatible with the CIFAR-10 dataset, which contains 10 classes.\n", + "2. **Define the CNN Model**:\n", + " - Use `Conv2dCustom` for convolutional layers.\n", + " - Use `MaxPool2dCustom` for pooling layers.\n", + " - Use standard `nn.Linear` for fully connected layers.\n", + " - The model should process input images of shape `(3, 32, 32)` as in the CIFAR-10 dataset.\n", "\n", + "### Constraints\n", + "- You must not use `nn.Conv2d` or `nn.MaxPool2d`. Use your own custom implementations.\n", + "- The CNN should include multiple convolutional and pooling layers, followed by fully connected layers.\n", + "- Ensure the model outputs class predictions for **10 classes**, as required by CIFAR-10.\n", "\n", "
\n", " ๐Ÿ’ก Hint\n", - " Add the convolutional (conv1, conv2), pooling (pool), and fully connected layers (fc1, fc2) in CNNModel.__init__.\n", - "
\n", - " Implement the forward pass to process inputs through these layers.\n", - "
" + " Define `Conv2dCustom` and `MaxPool2dCustom` as subclasses of `nn.Module`. Use nested loops and tensor slicing to perform the operations. \n", + " In `CNNModel.__init__`, use these custom layers to build the architecture. \n", + " Implement the forward pass to pass inputs through convolution, activation, pooling, flattening, and fully connected layers.\n", + "\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -39,7 +43,8 @@ "import torch.nn as nn\n", "import torch.optim as optim\n", "import torchvision\n", - "import torchvision.transforms as transforms" + "import torchvision.transforms as transforms\n", + "import torch.nn.functional as F" ] }, { @@ -91,6 +96,27 @@ "test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Conv2dCustom(nn.Module):\n", + " def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n", + "class MaxPool2dCustom(nn.Module):\n", + " def __init__(self, kernel_size, stride=None):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n" + ] + }, { "cell_type": "code", "execution_count": 3, diff --git a/torch/medium/cnn-scratch/CNN_scratch_SOLN.ipynb b/torch/medium/cnn-scratch/CNN_scratch_SOLN.ipynb new file mode 100644 index 0000000..b07bfad --- /dev/null +++ b/torch/medium/cnn-scratch/CNN_scratch_SOLN.ipynb @@ -0,0 +1,290 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Problem: Implement a CNN for CIFAR-10 (With Custom Layers)\n", + "\n", + "### Problem Statement\n", + "You are tasked with implementing a **Convolutional Neural Network (CNN)** for image classification on the **CIFAR-10** dataset using PyTorch. However, instead of using PyTorch's built-in `nn.Conv2d` and `nn.MaxPool2d`, you must implement these layers **from scratch** using `nn.Module`. Your model will include convolutional layers for feature extraction, pooling layers for downsampling, and fully connected layers for classification.\n", + "\n", + "### Requirements\n", + "1. **Implement Custom Layers**:\n", + " - Create a custom `Conv2dCustom` class that mimics the behavior of `nn.Conv2d`.\n", + " - Create a custom `MaxPool2dCustom` class that mimics the behavior of `nn.MaxPool2d`.\n", + "\n", + "2. **Define the CNN Model**:\n", + " - Use `Conv2dCustom` for convolutional layers.\n", + " - Use `MaxPool2dCustom` for pooling layers.\n", + " - Use standard `nn.Linear` for fully connected layers.\n", + " - The model should process input images of shape `(3, 32, 32)` as in the CIFAR-10 dataset.\n", + "\n", + "### Constraints\n", + "- You must not use `nn.Conv2d` or `nn.MaxPool2d`. Use your own custom implementations.\n", + "- The CNN should include multiple convolutional and pooling layers, followed by fully connected layers.\n", + "- Ensure the model outputs class predictions for **10 classes**, as required by CIFAR-10.\n", + "\n", + "
\n", + " ๐Ÿ’ก Hint\n", + " Define `Conv2dCustom` and `MaxPool2dCustom` as subclasses of `nn.Module`. Use nested loops and tensor slicing to perform the operations. \n", + " In `CNNModel.__init__`, use these custom layers to build the architecture. \n", + " Implement the forward pass to pass inputs through convolution, activation, pooling, flattening, and fully connected layers.\n", + "
\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torchvision\n", + "import torchvision.transforms as transforms\n", + "import torch.nn.functional as F" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\\cifar-10-python.tar.gz\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "8dcf56f0d6f941e48bd710768cad07e5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + " 0%| | 0/170498071 [00:00\n", - " ๐Ÿ’ก Hint\n", - " Add the convolutional (conv1, conv2), pooling (pool), and fully connected layers (fc1, fc2) in CNNModel.__init__.\n", - "
\n", - " Implement the forward pass to process inputs through these layers.\n", - "" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim\n", - "import torchvision\n", - "import torchvision.transforms as transforms" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data\\cifar-10-python.tar.gz\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "8dcf56f0d6f941e48bd710768cad07e5", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/170498071 [00:00 Date: Mon, 26 May 2025 11:48:13 -0700 Subject: [PATCH 31/40] AlexNet --- torch/medium/alexnet/alexnet.ipynb | 174 +++++++++++++++++++ torch/medium/alexnet/alexnet_SOLN.ipynb | 217 ++++++++++++++++++++++++ 2 files changed, 391 insertions(+) create mode 100644 torch/medium/alexnet/alexnet.ipynb create mode 100644 torch/medium/alexnet/alexnet_SOLN.ipynb diff --git a/torch/medium/alexnet/alexnet.ipynb b/torch/medium/alexnet/alexnet.ipynb new file mode 100644 index 0000000..a6a412a --- /dev/null +++ b/torch/medium/alexnet/alexnet.ipynb @@ -0,0 +1,174 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b61a94f9", + "metadata": {}, + "source": [ + "# Problem: Write AlexNet from Scratch\n", + "\n", + "### Problem Statement\n", + "Implement the **AlexNet architecture** in PyTorch by completing the required sections. The model should include convolutional layers, ReLU activations, pooling layers, and fully connected layers to process image data for classification tasks.\n", + "\n", + "### Requirements\n", + "\n", + "1. **Define the AlexNet Architecture**:\n", + " - **Feature Extractor (Convolutional Base)**:\n", + " - Stack convolutional layers with appropriate kernel sizes, strides, and paddings.\n", + " - Use `nn.ReLU` as the activation function after each convolution.\n", + " - Apply `nn.MaxPool2d` after selected layers to reduce spatial dimensions.\n", + " - **Classifier (Fully Connected Layers)**:\n", + " - Flatten the output from the convolutional base.\n", + " - Add fully connected layers with ReLU activations and dropout for regularization.\n", + " - End with a final linear layer projecting to the number of output classes.\n", + "\n", + "2. **Implement the Forward Method**:\n", + " - Pass the input image through the convolutional base.\n", + " - Flatten the feature map output to a vector.\n", + " - Pass it through the fully connected classifier to produce final predictions.\n", + "\n", + "3. **Weight Initialization**:\n", + " - Initialize weights of convolutional and linear layers using a normal distribution.\n", + " - Set biases to zero.\n", + "\n", + "### Constraints\n", + "- Assume input images are RGB with shape **(3, 224, 224)**.\n", + "- Ensure the model is compatible with **batch processing**.\n", + "- The final layer output size should match the number of target classes (e.g., 10 for CIFAR-10).\n", + "- Avoid using any pretrained models or high-level wrappers like `torchvision.models`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4bc452b", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torchvision\n", + "import torchvision.transforms as transforms\n", + "from torch.utils.data import DataLoader\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dc691770", + "metadata": {}, + "outputs": [], + "source": [ + "# Load data\n", + "transform = transforms.Compose([\n", + " transforms.Resize(224), # Resize to AlexNet input\n", + " transforms.ToTensor(),\n", + " transforms.Normalize((0.5,), (0.5,))\n", + "])\n", + "\n", + "train_set = torchvision.datasets.CIFAR10(root='./data', train=True,\n", + " download=True, transform=transform)\n", + "test_set = torchvision.datasets.CIFAR10(root='./data', train=False,\n", + " download=True, transform=transform)\n", + "\n", + "train_loader = DataLoader(train_set, batch_size=64, shuffle=True, num_workers=2)\n", + "test_loader = DataLoader(test_set, batch_size=64, shuffle=False, num_workers=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ca7c9dd", + "metadata": {}, + "outputs": [], + "source": [ + "# Define AlexNet\n", + "class AlexNet(nn.Module):\n", + " def __init__(self, num_classes=10): # Adjusted for CIFAR-10\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb0f03ea", + "metadata": {}, + "outputs": [], + "source": [ + "# --- Training setup ---\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model = AlexNet(num_classes=10).to(device)\n", + "\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(model.parameters(), lr=0.0001)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b1ed911", + "metadata": {}, + "outputs": [], + "source": [ + "num_epochs = 500\n", + "for epoch in range(num_epochs):\n", + " model.train()\n", + " running_loss = 0.0\n", + " correct = 0\n", + " total = 0\n", + "\n", + " for images, labels in train_loader:\n", + " images, labels = images.to(device), labels.to(device)\n", + "\n", + " outputs = model(images)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " running_loss += loss.item()\n", + " _, predicted = outputs.max(1)\n", + " total += labels.size(0)\n", + " correct += predicted.eq(labels).sum().item()\n", + "\n", + " print(f\"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss:.4f}, Accuracy: {100 * correct / total:.2f}%\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1626edd0", + "metadata": {}, + "outputs": [], + "source": [ + "model.eval()\n", + "correct = 0\n", + "total = 0\n", + "with torch.no_grad():\n", + " for images, labels in test_loader:\n", + " images, labels = images.to(device), labels.to(device)\n", + " outputs = model(images)\n", + " _, predicted = torch.max(outputs.data, 1)\n", + " total += labels.size(0)\n", + " correct += (predicted == labels).sum().item()\n", + "\n", + "print(f'Test Accuracy: {100 * correct / total:.2f}%')\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/torch/medium/alexnet/alexnet_SOLN.ipynb b/torch/medium/alexnet/alexnet_SOLN.ipynb new file mode 100644 index 0000000..4375d87 --- /dev/null +++ b/torch/medium/alexnet/alexnet_SOLN.ipynb @@ -0,0 +1,217 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b61a94f9", + "metadata": {}, + "source": [ + "# Problem: Write AlexNet from Scratch\n", + "\n", + "### Problem Statement\n", + "Implement the **AlexNet architecture** in PyTorch by completing the required sections. The model should include convolutional layers, ReLU activations, pooling layers, and fully connected layers to process image data for classification tasks.\n", + "\n", + "### Requirements\n", + "\n", + "1. **Define the AlexNet Architecture**:\n", + " - **Feature Extractor (Convolutional Base)**:\n", + " - Stack convolutional layers with appropriate kernel sizes, strides, and paddings.\n", + " - Use `nn.ReLU` as the activation function after each convolution.\n", + " - Apply `nn.MaxPool2d` after selected layers to reduce spatial dimensions.\n", + " - **Classifier (Fully Connected Layers)**:\n", + " - Flatten the output from the convolutional base.\n", + " - Add fully connected layers with ReLU activations and dropout for regularization.\n", + " - End with a final linear layer projecting to the number of output classes.\n", + "\n", + "2. **Implement the Forward Method**:\n", + " - Pass the input image through the convolutional base.\n", + " - Flatten the feature map output to a vector.\n", + " - Pass it through the fully connected classifier to produce final predictions.\n", + "\n", + "3. **Weight Initialization**:\n", + " - Initialize weights of convolutional and linear layers using a normal distribution.\n", + " - Set biases to zero.\n", + "\n", + "### Constraints\n", + "- Assume input images are RGB with shape **(3, 224, 224)**.\n", + "- Ensure the model is compatible with **batch processing**.\n", + "- The final layer output size should match the number of target classes (e.g., 10 for CIFAR-10).\n", + "- Avoid using any pretrained models or high-level wrappers like `torchvision.models`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a4bc452b", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torchvision\n", + "import torchvision.transforms as transforms\n", + "from torch.utils.data import DataLoader\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dc691770", + "metadata": {}, + "outputs": [], + "source": [ + "# Load data\n", + "transform = transforms.Compose([\n", + " transforms.Resize(224), # Resize to AlexNet input\n", + " transforms.ToTensor(),\n", + " transforms.Normalize((0.5,), (0.5,))\n", + "])\n", + "\n", + "train_set = torchvision.datasets.CIFAR10(root='./data', train=True,\n", + " download=True, transform=transform)\n", + "test_set = torchvision.datasets.CIFAR10(root='./data', train=False,\n", + " download=True, transform=transform)\n", + "\n", + "train_loader = DataLoader(train_set, batch_size=64, shuffle=True, num_workers=2)\n", + "test_loader = DataLoader(test_set, batch_size=64, shuffle=False, num_workers=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1ca7c9dd", + "metadata": {}, + "outputs": [], + "source": [ + "# Define AlexNet\n", + "class AlexNet(nn.Module):\n", + " def __init__(self, num_classes=10): # Adjusted for CIFAR-10\n", + " super(AlexNet, self).__init__()\n", + " self.features = nn.Sequential(\n", + " nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2),\n", + " nn.ReLU(inplace=True),\n", + " nn.MaxPool2d(kernel_size=3, stride=2),\n", + "\n", + " nn.Conv2d(96, 256, kernel_size=5, padding=2),\n", + " nn.ReLU(inplace=True),\n", + " nn.MaxPool2d(kernel_size=3, stride=2),\n", + "\n", + " nn.Conv2d(256, 384, kernel_size=3, padding=1),\n", + " nn.ReLU(inplace=True),\n", + "\n", + " nn.Conv2d(384, 384, kernel_size=3, padding=1),\n", + " nn.ReLU(inplace=True),\n", + "\n", + " nn.Conv2d(384, 256, kernel_size=3, padding=1),\n", + " nn.ReLU(inplace=True),\n", + " nn.MaxPool2d(kernel_size=3, stride=2)\n", + " )\n", + "\n", + " self.classifier = nn.Sequential(\n", + " nn.Dropout(),\n", + " nn.Linear(256 * 6 * 6, 4096),\n", + " nn.ReLU(inplace=True),\n", + " nn.Dropout(),\n", + " nn.Linear(4096, 4096),\n", + " nn.ReLU(inplace=True),\n", + " nn.Linear(4096, num_classes)\n", + " )\n", + "\n", + " self._initialize_weights()\n", + "\n", + " def forward(self, x):\n", + " x = self.features(x)\n", + " x = torch.flatten(x, 1)\n", + " x = self.classifier(x)\n", + " return x\n", + "\n", + " def _initialize_weights(self):\n", + " for m in self.modules():\n", + " if isinstance(m, nn.Conv2d):\n", + " nn.init.normal_(m.weight, mean=0.0, std=0.01)\n", + " nn.init.constant_(m.bias, 0)\n", + " elif isinstance(m, nn.Linear):\n", + " nn.init.normal_(m.weight, mean=0.0, std=0.01)\n", + " nn.init.constant_(m.bias, 0)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb0f03ea", + "metadata": {}, + "outputs": [], + "source": [ + "# --- Training setup ---\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model = AlexNet(num_classes=10).to(device)\n", + "\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(model.parameters(), lr=0.0001)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9b1ed911", + "metadata": {}, + "outputs": [], + "source": [ + "num_epochs = 500\n", + "for epoch in range(num_epochs):\n", + " model.train()\n", + " running_loss = 0.0\n", + " correct = 0\n", + " total = 0\n", + "\n", + " for images, labels in train_loader:\n", + " images, labels = images.to(device), labels.to(device)\n", + "\n", + " outputs = model(images)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " optimizer.zero_grad()\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " running_loss += loss.item()\n", + " _, predicted = outputs.max(1)\n", + " total += labels.size(0)\n", + " correct += predicted.eq(labels).sum().item()\n", + "\n", + " print(f\"Epoch [{epoch+1}/{num_epochs}], Loss: {running_loss:.4f}, Accuracy: {100 * correct / total:.2f}%\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1626edd0", + "metadata": {}, + "outputs": [], + "source": [ + "model.eval()\n", + "correct = 0\n", + "total = 0\n", + "with torch.no_grad():\n", + " for images, labels in test_loader:\n", + " images, labels = images.to(device), labels.to(device)\n", + " outputs = model(images)\n", + " _, predicted = torch.max(outputs.data, 1)\n", + " total += labels.size(0)\n", + " correct += (predicted == labels).sum().item()\n", + "\n", + "print(f'Test Accuracy: {100 * correct / total:.2f}%')\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 629e73fbb6d0cad6b9db75b51e72e37f012d210d Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 11:52:39 -0700 Subject: [PATCH 32/40] Link updates --- README.md | 58 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index bda2b2b..7e6ed2d 100644 --- a/README.md +++ b/README.md @@ -34,48 +34,46 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st ### ๐Ÿ”ตBasic Mostly for beginners to get started with PyTorch. -1. [Implement linear regression](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e1/lin-regression_SOLN.ipynb) -2. [Write a custom Dataset and Dataloader to load from a CSV file](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e2/custom-dataset_SOLN.ipynb) -3. [Write a custom activation function (Simple)](https://github.com/Exorust/TorchLeet/torch/easy/e3/custom-activation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/blob/main/e3/custom-activation_SOLN.ipynb) -4. [Implement Custom Loss Function (Huber Loss)](https://github.com/Exorust/TorchLeet/torch/easy/main/e4/custom-loss.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/main/e4/custom-loss_SOLN.ipynb) -5. [Implement a Deep Neural Network](https://github.com/Exorust/TorchLeet/torch/easy/e5/custon-DNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e5/custon-DNN_SOLN.ipynb) -6. [Visualize Training Progress with TensorBoard in PyTorch](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e6/tensorboard_SOLN.ipynb) -7. [Save and Load Your PyTorch Model](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/easy/e7/save_model_SOLN.ipynb) +1. [Implement linear regression](torch/easy/e1/lin-regression.ipynb) [(Solution)](torch/easy/e1/lin-regression_SOLN.ipynb) +2. [Write a custom Dataset and Dataloader to load from a CSV file](torch/easy/e2/custom-dataset.ipynb) [(Solution)](torch/easy/e2/custom-dataset_SOLN.ipynb) +3. [Write a custom activation function (Simple)](torch/easy/e3/custom-activation.ipynb) [(Solution)](torch/easy/e3/custom-activation_SOLN.ipynb) +4. [Implement Custom Loss Function (Huber Loss)](torch/easy/e4/custom-loss.ipynb) [(Solution)](torch/easy/e4/custom-loss_SOLN.ipynb) +5. [Implement a Deep Neural Network](torch/easy/e5/custon-DNN.ipynb) [(Solution)](torch/easy/e5/custon-DNN_SOLN.ipynb) +6. [Visualize Training Progress with TensorBoard in PyTorch](torch/easy/e6/tensorboard.ipynb) [(Solution)](torch/easy/e6/tensorboard_SOLN.ipynb) +7. [Save and Load Your PyTorch Model](torch/easy/e7/save_model.ipynb) [(Solution)](torch/easy/e7/save_model_SOLN.ipynb) 10. Implement Softmax function from scratch ### ๐ŸŸขEasy Recommended for those who have a basic understanding of PyTorch and want to practice their skills. -1. [Implement a CNN on CIFAR-10](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m2/CNN_SOLN.ipynb) -2. [Implement an RNN from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m3/RNN_SOLN.ipynb) -3. [Use `torchvision.transforms` to apply data augmentation](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m4/augmentation_SOLN.ipynb) -4. [Add a benchmark to your PyTorch code](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m5/bench_SOLN.ipynb) -5. [Train an autoencoder for anomaly detection](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m6/autoencoder_SOLN.ipynb) -6. [Quantize your language model](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h6/quantize-language-model_SOLN.ipynb) -7. [Implement Mixed Precision Training using torch.cuda.amp](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h9/cuda-amp_SOLN.ipynb) +1. [Implement a CNN on CIFAR-10](torch/medium/m2/CNN.ipynb) [(Solution)](torch/medium/m2/CNN_SOLN.ipynb) +2. [Implement an RNN from Scratch](torch/medium/m3/RNN.ipynb) [(Solution)](torch/medium/m3/RNN_SOLN.ipynb) +3. [Use `torchvision.transforms` to apply data augmentation](torch/medium/m4/augmentation.ipynb) [(Solution)](torch/medium/m4/augmentation_SOLN.ipynb) +4. [Add a benchmark to your PyTorch code](torch/medium/m5/bench.ipynb) [(Solution)](torch/medium/m5/bench_SOLN.ipynb) +5. [Train an autoencoder for anomaly detection](torch/medium/m6/autoencoder.ipynb) [(Solution)](torch/medium/m6/autoencoder_SOLN.ipynb) +6. [Quantize your language model](torch/hard/h6/quantize-language-model.ipynb) [(Solution)](torch/hard/h6/quantize-language-model_SOLN.ipynb) +7. [Implement Mixed Precision Training using torch.cuda.amp](torch/hard/h9/cuda-amp.ipynb) [(Solution)](torch/hard/h9/cuda-amp_SOLN.ipynb) ### ๐ŸŸกMedium These problems are designed to challenge your understanding of PyTorch and deep learning concepts. They require you to implement things from scratch or apply advanced techniques. 1. [Implement parameter initialization for a CNN]() [(Solution)]() 2. [Implement a CNN from Scratch]() -3. [Implement an LSTM from Scratch](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/medium/m1/LSTM_SOLN.ipynb) +3. [Implement an LSTM from Scratch](torch/medium/m1/LSTM.ipynb) [(Solution)](torch/medium/m1/LSTM_SOLN.ipynb) 4. Implement AlexNet from scratch 5. Build a Dense Retrieval System using PyTorch 6. Implement KNN from scratch in PyTorch -** Finding these too easy? Try implementing in an empty ntbk** - ### ๐Ÿ”ดHard These problems are for advanced users who want to push their PyTorch skills to the limit. They involve complex architectures, custom layers, and advanced techniques. -1. [Write a custom Autograd function for activation (SILU)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h1/custom-autgrad-function_SOLN.ipynb) +1. [Write a custom Autograd function for activation (SILU)](torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](torch/hard/h1/custom-autgrad-function_SOLN.ipynb) 2. Write a Neural Style Transfer 3. Build a Graph Neural Network (GNN) from scratch 4. Build a Graph Convolutional Network (GCN) from scratch -5. [Write a Transformer](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h3/transformer_SOLN.ipynb) -6. [Write a GAN](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h4/GAN_SOLN.ipynb) -7. [Write Sequence-to-Sequence with Attention](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb) +5. [Write a Transformer](torch/hard/h3/transformer.ipynb) [(Solution)](torch/hard/h3/transformer_SOLN.ipynb) +6. [Write a GAN](torch/hard/h4/GAN.ipynb) [(Solution)](torch/hard/h4/GAN_SOLN.ipynb) +7. [Write Sequence-to-Sequence with Attention](torch/hard/h5/seq-to-seq-with-Attention.ipynb) [(Solution)](torch/hard/h5/seq-to-seq-with-Attention_SOLN.ipynb) 8. [Enable distributed training in pytorch (DistributedDataParallel)] 9. [Work with Sparse Tensors] -10. [Add GradCam/SHAP to explain the model.](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/hard/h10/xai_SOLN.ipynb) +10. [Add GradCam/SHAP to explain the model.](torch/hard/h10/xai.ipynb) [(Solution)](torch/hard/h10/xai_SOLN.ipynb) 11. Linear Probe on CLIP Features 12. Add Cross Modal Embedding Visualization to CLIP (t-SNE/UMAP) 13. Implement a Vision Transformer @@ -87,16 +85,16 @@ These problems are for advanced users who want to push their PyTorch skills to t 1. Implement KL Divergence Loss 2. Implement RMS Norm -3. [Implement Byte Pair Encoding from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Byte-Pair-Encoding/BPE-q3.ipynb) -4. [Create an embeddings out of an LLM](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) +3. [Implement Byte Pair Encoding from Scratch](llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](llm/Byte-Pair-Encoding/BPE-q3.ipynb) +4. [Create an embeddings out of an LLM](llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) 5. Implement Predictive Prefill with Speculative Decoding -6. [Implement Attention from Scratch ](https://github.com/Exorust/TorchLeet/torch/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Implement-Attention-from-Scratch/attention-q4.ipynb) -7. [Implement Multi-Head Attention from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Multi-Head-Attention/multi-head-attention-q5.ipynb) -8. [Implement Grouped Query Attention from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Grouped-Query-Attention/grouped-query-attention.ipynb) +6. [Implement Attention from Scratch](llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb)[(Solution)](llm/Implement-Attention-from-Scratch/attention-q4.ipynb) +7. [Implement Multi-Head Attention from Scratch](llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb)[(Solution)](llm/Multi-Head-Attention/multi-head-attention-q5.ipynb) +8. [Implement Grouped Query Attention from Scratch](llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb)[(Solution)](llm/Grouped-Query-Attention/grouped-query-attention.ipynb) 9. Implement KV Cache in Multi-Head Attention from Scratch -10. [Implement Sinusoidal Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) -11. [Implement ROPE Embeddings](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/Rotary-Positional-Embedding/rope-q8.ipynb) -12. [Implement SmolLM from Scratch](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](https://github.com/Exorust/TorchLeet/torch/llm/SmolLM/smollm-q12.ipynb) +10. [Implement Sinusoidal Embeddings](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb)[(Solution)](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) +11. [Implement ROPE Embeddings](llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](llm/Rotary-Positional-Embedding/rope-q8.ipynb) +12. [Implement SmolLM from Scratch](llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](llm/SmolLM/smollm-q12.ipynb) 13. Implement Quantization of Models 1. GPTQ 14. Implement Beam Search atop LLM for decoding From 2be72e885f1882216ef9c72f8622450d1e35ad82 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 11:56:31 -0700 Subject: [PATCH 33/40] Changes --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7e6ed2d..d22a826 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,8 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st ### ๐Ÿ”ตBasic Mostly for beginners to get started with PyTorch. -1. [Implement linear regression](torch/easy/e1/lin-regression.ipynb) [(Solution)](torch/easy/e1/lin-regression_SOLN.ipynb) -2. [Write a custom Dataset and Dataloader to load from a CSV file](torch/easy/e2/custom-dataset.ipynb) [(Solution)](torch/easy/e2/custom-dataset_SOLN.ipynb) +1. [Implement linear regression](torch/basic/lin-regression/lin-regression.ipynb) [(Solution)](torch/basic/lin-regression/lin-regression_SOLN.ipynb) +2. [Write a custom Dataset and Dataloader to load from a CSV file](torch/basic/custom-dataset/custom-dataset.ipynb) [(Solution)](torch/basic/custom-dataset/custom-dataset_SOLN.ipynb) 3. [Write a custom activation function (Simple)](torch/easy/e3/custom-activation.ipynb) [(Solution)](torch/easy/e3/custom-activation_SOLN.ipynb) 4. [Implement Custom Loss Function (Huber Loss)](torch/easy/e4/custom-loss.ipynb) [(Solution)](torch/easy/e4/custom-loss_SOLN.ipynb) 5. [Implement a Deep Neural Network](torch/easy/e5/custon-DNN.ipynb) [(Solution)](torch/easy/e5/custon-DNN_SOLN.ipynb) From 60d933e22a0452fbc6138111d70dd2dbe7a73464 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 12:08:03 -0700 Subject: [PATCH 34/40] Transformer change --- torch/hard/transformer/transformer.ipynb | 101 ++++++++---- torch/hard/transformer/transformer_SOLN.ipynb | 156 +++++++++++++----- 2 files changed, 188 insertions(+), 69 deletions(-) diff --git a/torch/hard/transformer/transformer.ipynb b/torch/hard/transformer/transformer.ipynb index 1fda52e..a9eb317 100644 --- a/torch/hard/transformer/transformer.ipynb +++ b/torch/hard/transformer/transformer.ipynb @@ -4,41 +4,51 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Problem: Write a Transformer\n", - "\n", - "### Problem Statement\n", - "Implement a **Transformer model** in PyTorch by completing the required sections. The model should consist of an embedding layer, a Transformer encoder, and an output layer for sequence processing and prediction.\n", - "\n", - "### Requirements\n", - "1. **Define the Transformer Model Architecture**:\n", - " - **Embedding Layer**:\n", - " - Implement a layer to transform input data into a higher-dimensional space.\n", - " - Use a `torch.nn.Linear` or `torch.nn.Embedding` layer to create embeddings from the input.\n", - " - **Transformer Encoder**:\n", - " - Use `torch.nn.TransformerEncoder` or `torch.nn.Transformer` to process sequences with attention.\n", - " - Configure parameters such as the number of attention heads and encoder layers.\n", - " - **Output Layer**:\n", - " - Add a fully connected (linear) layer to reduce the transformer's sequence output into the desired output dimension.\n", - "\n", - "2. **Implement the Forward Method**:\n", - " - Map the input to the higher-dimensional space using the embedding layer.\n", - " - Pass the transformed input through the Transformer encoder.\n", - " - Use the output layer to convert the encoded sequence into predictions.\n", - "\n", - "### Constraints\n", - "- Handle input padding correctly for variable-length sequences.\n", - "- Ensure compatibility with batch processing by correctly shaping input and output tensors.\n" + "# Problem: Build a Transformer Model from Scratch\n", + "\n", + "## Objective\n", + "Implement a **Transformer model** in PyTorch for sequence processing and prediction. The model should include an embedding layer, a Transformer encoder, and an output projection layer.\n", + "\n", + "## Tasks\n", + "\n", + "1. Implement Positional Encoding to inject sequence order into embeddings \n", + "Create sinusoidal positional encodings that are added to input embeddings to provide order information.\n", + "\n", + "2. Implement Multi-Head Self Attention mechanism \n", + "Apply attention in parallel across multiple heads to capture different representation subspaces.\n", + "\n", + "3. Linear projection of queries, keys, and values \n", + "Use a single linear layer to project input into concatenated Q, K, V tensors.\n", + "\n", + "4. Scaled dot-product attention \n", + "Compute attention scores by scaled dot product of queries and keys, followed by softmax and application to values.\n", + "\n", + "5. Output projection after head concatenation \n", + "Concatenate the outputs of all heads and project back to the original embedding dimension.\n", + "\n", + "6. Implement FeedForward layer used within Transformer blocks \n", + "Build a two-layer MLP with a ReLU activation in between to process each token independently.\n", + "\n", + "7. Connect components in a TransformerEncoderLayer with proper layer normalization and residual connections \n", + "Apply residual connections and layer normalization around the attention and feedforward sublayers.\n", + "\n", + "\n", + "## Requirements\n", + "\n", + "- Support padded input sequences for variable-length data.\n", + "- Ensure the model handles batched inputs with correct tensor shapes.\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", - "import torch.optim as optim" + "import torch.optim as optim\n", + "import math" ] }, { @@ -47,16 +57,43 @@ "metadata": {}, "outputs": [], "source": [ - "# Define a Transformer Model\n", - "#TODO: Implement a Transformer model\n", + "class PositionalEncoding(nn.Module):\n", + " def __init__(self, d_model, max_len=5000):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n", + "\n", + "class MultiHeadSelfAttention(nn.Module):\n", + " def __init__(self, embed_dim, num_heads):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n", + "\n", + "class FeedForward(nn.Module):\n", + " def __init__(self, embed_dim, ff_dim):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n", + "\n", + "class TransformerEncoderLayer(nn.Module):\n", + " def __init__(self, embed_dim, num_heads, ff_dim):\n", + " ...\n", + "\n", + " def forward(self, x):\n", + " ...\n", + "\n", "class TransformerModel(nn.Module):\n", " def __init__(self, input_dim, embed_dim, num_heads, num_layers, ff_dim, output_dim):\n", - " super(TransformerModel, self).__init__()\n", - " # Add layers and modules for embedding, transformer, and output\n", + " ...\n", "\n", " def forward(self, x):\n", - " # Define the forward pass logic\n", - " ..." + " ...\n" ] }, { diff --git a/torch/hard/transformer/transformer_SOLN.ipynb b/torch/hard/transformer/transformer_SOLN.ipynb index cfa52ac..e5ab3aa 100644 --- a/torch/hard/transformer/transformer_SOLN.ipynb +++ b/torch/hard/transformer/transformer_SOLN.ipynb @@ -4,63 +4,145 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Problem: Write a Transformer\n", - "\n", - "### Problem Statement\n", - "Implement a **Transformer model** in PyTorch by completing the required sections. The model should consist of an embedding layer, a Transformer encoder, and an output layer for sequence processing and prediction.\n", - "\n", - "### Requirements\n", - "1. **Define the Transformer Model Architecture**:\n", - " - **Embedding Layer**:\n", - " - Implement a layer to transform input data into a higher-dimensional space.\n", - " - Use a `torch.nn.Linear` or `torch.nn.Embedding` layer to create embeddings from the input.\n", - " - **Transformer Encoder**:\n", - " - Use `torch.nn.TransformerEncoder` or `torch.nn.Transformer` to process sequences with attention.\n", - " - Configure parameters such as the number of attention heads and encoder layers.\n", - " - **Output Layer**:\n", - " - Add a fully connected (linear) layer to reduce the transformer's sequence output into the desired output dimension.\n", - "\n", - "2. **Implement the Forward Method**:\n", - " - Map the input to the higher-dimensional space using the embedding layer.\n", - " - Pass the transformed input through the Transformer encoder.\n", - " - Use the output layer to convert the encoded sequence into predictions.\n", - "\n", - "### Constraints\n", - "- Handle input padding correctly for variable-length sequences.\n", - "- Ensure compatibility with batch processing by correctly shaping input and output tensors.\n" + "# Problem: Build a Transformer Model from Scratch\n", + "\n", + "## Objective\n", + "Implement a **Transformer model** in PyTorch for sequence processing and prediction. The model should include an embedding layer, a Transformer encoder, and an output projection layer.\n", + "\n", + "## Tasks\n", + "\n", + "1. Implement Positional Encoding to inject sequence order into embeddings \n", + "Create sinusoidal positional encodings that are added to input embeddings to provide order information.\n", + "\n", + "2. Implement Multi-Head Self Attention mechanism \n", + "Apply attention in parallel across multiple heads to capture different representation subspaces.\n", + "\n", + "3. Linear projection of queries, keys, and values \n", + "Use a single linear layer to project input into concatenated Q, K, V tensors.\n", + "\n", + "4. Scaled dot-product attention \n", + "Compute attention scores by scaled dot product of queries and keys, followed by softmax and application to values.\n", + "\n", + "5. Output projection after head concatenation \n", + "Concatenate the outputs of all heads and project back to the original embedding dimension.\n", + "\n", + "6. Implement FeedForward layer used within Transformer blocks \n", + "Build a two-layer MLP with a ReLU activation in between to process each token independently.\n", + "\n", + "7. Connect components in a TransformerEncoderLayer with proper layer normalization and residual connections \n", + "Apply residual connections and layer normalization around the attention and feedforward sublayers.\n", + "\n", + "\n", + "## Requirements\n", + "\n", + "- Support padded input sequences for variable-length data.\n", + "- Ensure the model handles batched inputs with correct tensor shapes.\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import torch\n", "import torch.nn as nn\n", - "import torch.optim as optim" + "import torch.optim as optim\n", + "import math" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Define a Transformer Model\n", + "class PositionalEncoding(nn.Module):\n", + " def __init__(self, d_model, max_len=5000):\n", + " super().__init__()\n", + " pe = torch.zeros(max_len, d_model)\n", + " position = torch.arange(0, max_len).unsqueeze(1)\n", + " div_term = torch.exp(torch.arange(0, d_model, 2) * (-math.log(10000.0) / d_model))\n", + "\n", + " pe[:, 0::2] = torch.sin(position * div_term) # Even indices\n", + " pe[:, 1::2] = torch.cos(position * div_term) # Odd indices\n", + "\n", + " pe = pe.unsqueeze(0) # Shape: [1, max_len, d_model]\n", + " self.register_buffer('pe', pe)\n", + "\n", + " def forward(self, x):\n", + " seq_len = x.size(1)\n", + " return x + self.pe[:, :seq_len]\n", + "\n", + "\n", + "class MultiHeadSelfAttention(nn.Module):\n", + " def __init__(self, embed_dim, num_heads):\n", + " super().__init__()\n", + " assert embed_dim % num_heads == 0, \"Embedding dimension must be divisible by number of heads\"\n", + "\n", + " self.num_heads = num_heads\n", + " self.head_dim = embed_dim // num_heads\n", + "\n", + " self.qkv_proj = nn.Linear(embed_dim, 3 * embed_dim)\n", + " self.out_proj = nn.Linear(embed_dim, embed_dim)\n", + "\n", + " def forward(self, x):\n", + " B, T, D = x.shape\n", + " qkv = self.qkv_proj(x) # Shape: (B, T, 3*D)\n", + " qkv = qkv.reshape(B, T, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)\n", + " q, k, v = qkv[0], qkv[1], qkv[2] # Each is (B, num_heads, T, head_dim)\n", + "\n", + " scores = (q @ k.transpose(-2, -1)) / math.sqrt(self.head_dim) # (B, num_heads, T, T)\n", + " attn_weights = torch.softmax(scores, dim=-1)\n", + " attn_output = attn_weights @ v # (B, num_heads, T, head_dim)\n", + "\n", + " attn_output = attn_output.transpose(1, 2).reshape(B, T, D)\n", + " return self.out_proj(attn_output)\n", + "\n", + "\n", + "class FeedForward(nn.Module):\n", + " def __init__(self, embed_dim, ff_dim):\n", + " super().__init__()\n", + " self.linear1 = nn.Linear(embed_dim, ff_dim)\n", + " self.relu = nn.ReLU()\n", + " self.linear2 = nn.Linear(ff_dim, embed_dim)\n", + "\n", + " def forward(self, x):\n", + " return self.linear2(self.relu(self.linear1(x)))\n", + "\n", + "\n", + "class TransformerEncoderLayer(nn.Module):\n", + " def __init__(self, embed_dim, num_heads, ff_dim):\n", + " super().__init__()\n", + " self.attn = MultiHeadSelfAttention(embed_dim, num_heads)\n", + " self.ffn = FeedForward(embed_dim, ff_dim)\n", + " self.norm1 = nn.LayerNorm(embed_dim)\n", + " self.norm2 = nn.LayerNorm(embed_dim)\n", + "\n", + " def forward(self, x):\n", + " x = self.norm1(x + self.attn(x))\n", + " x = self.norm2(x + self.ffn(x))\n", + " return x\n", + "\n", + "\n", "class TransformerModel(nn.Module):\n", " def __init__(self, input_dim, embed_dim, num_heads, num_layers, ff_dim, output_dim):\n", - " super(TransformerModel, self).__init__()\n", - " self.embedding = nn.Linear(input_dim, embed_dim)\n", - " encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads, dim_feedforward=ff_dim)\n", - " self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)\n", - " self.output_layer = nn.Linear(embed_dim, output_dim)\n", + " super().__init__()\n", + " self.input_proj = nn.Linear(input_dim, embed_dim)\n", + " self.pos_encoding = PositionalEncoding(embed_dim)\n", + " self.layers = nn.ModuleList([\n", + " TransformerEncoderLayer(embed_dim, num_heads, ff_dim)\n", + " for _ in range(num_layers)\n", + " ])\n", + " self.output_proj = nn.Linear(embed_dim, output_dim)\n", "\n", " def forward(self, x):\n", - " x = self.embedding(x)\n", - " x = self.transformer(x)\n", - " x = x.mean(dim=1) # Pooling across the sequence\n", - " return self.output_layer(x)" + " x = self.input_proj(x)\n", + " x = self.pos_encoding(x)\n", + " for layer in self.layers:\n", + " x = layer(x)\n", + " x = x.mean(dim=1) # Global average pooling over sequence length\n", + " return self.output_proj(x)\n" ] }, { From 2c22fb0713faa0db01be79f3c696341c89dcb001 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 12:21:33 -0700 Subject: [PATCH 35/40] New README --- README.md | 5 ++++- torchleet-llm.png | Bin 0 -> 29675 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 torchleet-llm.png diff --git a/README.md b/README.md index d22a826..f8be265 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- Robot Image + Robot Image

๐Ÿฆ Follow me on Twitter โ€ข @@ -17,6 +17,7 @@ TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-st - [TorchLeet](#torchleet) - [Table of Contents](#table-of-contents) - [Question Set](#question-set) + - [๐Ÿ”ตBasic](#basic) - [๐ŸŸขEasy](#easy) - [๐ŸŸกMedium](#medium) - [๐Ÿ”ดHard](#hard) @@ -83,6 +84,8 @@ These problems are for advanced users who want to push their PyTorch skills to t **An all new set of questions to help you understand and implement Large Language Models from scratch.** +Each question is designed to take you one step closer to building your own LLM. + 1. Implement KL Divergence Loss 2. Implement RMS Norm 3. [Implement Byte Pair Encoding from Scratch](llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](llm/Byte-Pair-Encoding/BPE-q3.ipynb) diff --git a/torchleet-llm.png b/torchleet-llm.png new file mode 100644 index 0000000000000000000000000000000000000000..5bd6f94322540bc4e62b87a7a07c4c2ee06ce6dc GIT binary patch literal 29675 zcmeFZ^;?u}_dbf9C|F1f2#Cs{gfu8Aje;OCV9+r%!T`c!5F#BTE!`juBjF=RNY@}z zN;lHddtE%AYNI z<0A5h*%xOtm`ZzyACD4V4NJ5=e4zX4)clF-m(JfSJ}k}q@uSZriB|{NW>5G|uCLee z{3euD83*%(L^MPM|Gd}f=>NX;e^=mtSKxnF;QyNyP?D;dWQMFXthPMfJoc7K zFEB+Z>ifN8^jDRl?vVd=FDe)w zN*d+rPxD-Qr`gqF)r!;1%++3J&t5)DMs|gAKjZxgy!ZNO!}i9qLoc^MJw-!fW2a%4 zq?uX9P2Eye0w<4AQ=oZHnGAttoWE+r&tkA#i@+K8ax*>JZLODh8ZxUho$VR;50l&0 zS~sh#FBKPwwX5^Iib%YIe?o6lC`IuB{$@?M2d;$p6X<=oGlqi|E+w-ApEU^&&Xx?l z{Jb*RE=k~|!rBL6q@(*h$Jygt6BOV#PWl0RcdO)`S{aag6dhZI2E|Dq{i?g zr!LhCFO(-XQcf7rQc!9Yngn4WXJ0)`6A8b_(4HWDYNOfeWn$wcn#iElzas%N!HGjV z^Dl@OF5+5!%iOjcu?Nq6Et`nF5g@wu!F7G$h3#mN?6mkHGMWRJlZVMp7|r*WbyT^# zQwDk57|_@gClzf@x5dA<_*p1N_(x`{->x+*Kz#QxfpcebHDr6+6)SVOqoZTAs7J5U zuyJT__eF$=b3R5^cWZ6VaHQ6cXrYyF;B)%&t-FK+Dw{)lJNndjEIyp37g8rW&e8lS zx&LyUjLhj6MA`jYeI-@|jco0yeB(vwBY*dH7X#euCC`e&U5__M*_~-VzOh)xm@Mga zhDi4@D@#$xVLGYtfz9u?R79byo!?%J;jl1jgafTkEA6s|lWp-G6)rD!QV(flJ!TSh zS?e++yUX&0X@V^9uD`&r_Zu@Kj83s4!9%9Gx$Hc@)u18|k3_7~u#Zqw#D1*wB&XRF zkRR6+@Tw~^?@`8;jfHEYe`0i7K}$|^0#-cmZvV^n)pr}q6Eo-9(#o9u?RJ~$C;Lir z-!qEq{TD-zGBu`byGnbHO1)7#^QE&tmi-Ptzb1i<%=I5Zm?*l;Xe0?v6-96+c)1@!o6u zhRz?=$N%p2&qtIz`*sp5;f*6sv1z(^W9{3ei5DKp(mR9}nzTzm2)i!9H^mN*Z?H4x zyYIck9wg&E2X+6-KS?Pm)4|4by#=z@uV1&PHYx0%&y$iYc;Y2rMaS7+bL?Y`@( zNj2efwM5Bst>bM^nc(nME-n>xGsn@*P+0yfY=@gEcglmCiH!0bUmtRBJ@U`=ln;As z8>=jpo>M$Vnx0&V_h=oR-TO?@AVGIFGG5$&r~QkIc99t?#7yTHUT`c_ZL~vytJ|=# z+lFXDLD=4$cGjlP_f0;zHbjcClq&N}~t6E-XpT;2s3%jUz{nz)?1lI?eQkVmOpN z*6C~MZP&ln=DHI1M}tE{lj0oxaizbHn(GdWiEsaTU8%r1)010L>-*^XjT@`OkJsi0 z%>87&3Ea+01{GSu9V3(y$4zyA2ilR{RXudb4GE)=VT}8mJN@O01Yjb^Y z{LvvjNbwZ6*0#OW$W?Yl^+Uhj@kvOH-N_$p`r34f_URB1?PYexrX5K>7@bQuAAeLJ z^N{g`B=qG0Bt(qhu(jQl&3@hEo)tXRJh*;=siCSWjLyrwt)ZERimUSjIt02r`Y(HRFR;?gO>h56C)e@7n)ar;n9D_vIZ8dueJ{(A;dZ31UQ zLjyTJ=a+JfP{Zcx4Ahwy^ZiFZn>>)5`H`3S*Huh#*qa4?c?V?e{p%heK7t@+>npYl zahM@ZwTom!wzGxRLYFz}&Eg+eeMb1^6Soq0)85X4`>KhJ<;K!jM}e^l_KfPohs-g; zFGwiQp#b_-|A9Ef0FgTOsrpQ(VXH|`PRwaKfj@VZ#dqx8&dWyKu?&8Dii)BBd)SRt zrDwzLd+Y9FP%#KlY3RI*4I0jA6aaD2bNZU8?d5!)4?f1=beF&h8_%lx)>cG)%+fj4qWzc$5*>*p%}xP;L)!Bng~G#6`c$)LQ) zvKDEWp>~(*@yfnFcDA@yDJk0Vr|CH4=3BIPEZQ;|!h?g)E&qCbHZnw6s3B6bd=#RA z|E$>Gj~lyN3#-FkW2td3xzQ&~^%kV^kjF`#!+!Fbsa5#lyCZ){j-y>8X zxGMij1ZZ({JuVfojU+zC+%bqoQs&rX6HjYlt);i?QUg1_ovsKs@RNq0lH2;%-DTLf$!@>2 zsm|1>q3v;gQaSB)xFe$Th#&vTGnuZ;+)6WLf!~MC2Ui;s1H>|nM+CVlR)UN4-cU#k zb8GxVA#tBY#mFdS*L7j?)hW!UTEDt}{7m-vM4UUxmyr(;<1M8~-n?*@4vw2Qy9$b< zZNGDnoVw+dl^u%+#-;iB`B~1j-0+R~nkZ+SwAn%`oP}vQVd89lW0p;B)h^zxzz!wsgyhn&h+%R0*e7+Hw_mhw`s@Kii`&ZmVI|nA~vUf7K2a^m$v$V zLl2h3{U!?1y{L05HILEz|JQ}L67*lDiw_B#!9n1|i5UL+@{dtNFe^Uq`Ll2DE~dx^ zFp#*VxeW~s@x|eg&$LH;_9{6r7!rR#X&r-06Kqvy-gDXIl}?ozX&;UX#otEtflT-g z|1)BLe|apXsKn)1owK2)rY0@nnE=IfWDegC=uutVaD_cEG&a^5!3)AVRc=gY=B}94 zN=aJw0rD~bw4Rk3i~p`2YaM*tY>O!nmRR@ObvQw$qc(~8`5iP|v9^7dB~#M=WqjtO z4|gnoK5o2}uKwuJl$Q32z_~He_2~C>f*snPCSwckd!P5SHgipvCpm4_*h&5uLvAIp z`HrpU!)sw?6V}5>M6q2Hx-(8 zu1tUHPm&ACGW0cKaQ$^)j$ZQh7F0^@-vxXKM9^Ns%TVP7s%$Z|BS*yI1#H6|q|PqnW5quVj>_f&>5(+t^r zHGxue+Zp+Y@D@{yB6kawI@}FxtLD z&ghHBfpLI6{E$|jV*h59m-o}Tt+bQ!Ww`Ceo7xK;#^9ZIUJN)8$^acTLt|wA@Zm#6 zKmkfsFLx9nD@Sk}%Kz}n^>VqLm9CaLE$7_Q6v30d%KV1nT%76f9yFB9%-ohgdCPu# z(gH+&R&zXp$Jigkk2=wMXfMa2?ONL1GrD{9-8mUw{*8x9Ca!C< z2DOOOCkW$*Ii5}{Y{ky%OMYSh+$XW4iRl*@xr~aFIAm zO)q30C}=l+KUc3}CGOQGRD>}oSb=cNdaK;4b_)`pR(m%5T^t#M_3Uv!c^z)0qqEbY zY!DLD6SNcCYb90P?kCM4*>M|wzYxK16|1hHF)c1kbL)x6dwO9FXkX!z@vx#}=-`YA ziLQ33br2oQv5sSfoys8y5D++9MV8-Vq`RO+XU;8OdWShgHXPbLcJ&QKhtr6oRn2}q zDJ749UB+@f%dXs-7q)BW>v`O16Efm2+*1DM>nVJ2Q6%)nd@-A&x$Zlev2T+%+j;?V zPKyg}uJ-6R*Z7=Q0=6T2L(s78<30Sjdlj40nWVp~&0qdGq$DlcCp%9i6Aq^2T2bNp^(ZF4-^hiw!#1<*KF$lq&@5$-un&0Q0zd~KsMZa0aYR{d(L zk4_ALWiNZY_p4V2m$!!Y2H~H}mRp3IcXzf{lU|#3XN2+jnT*3>BKbb)Ei?_`V_@PsOweWmm|C*`{wowic@NRfN(Y8$>~4)DbCD+E8ELR`5wN zPHe#2TdM>Yvm3%HEN@{@tM=2=>a4|?^Zd=9&7jbKsy)jO zhqE)}>@=)+VQqj>fAktzVxnFgKO0LBF~u8*6#y`<(ckxY8~wtJ+% zzuCI%j9Q}jTTxOY*$)e%RH8?&U}KYqIr5{#O8*Dd9n+tM>AjV1pJS5@0YC%p3Pz#J zm6JF3AqBUzJBOUe8EQP1PCc;l~XM zzrQ`+z#dmv>!$&nT8i;PeWss_#BrtvzK^azz~ARF>$-++49FP+zdi~l zx0-SHi65hnuFbcLcn$y9mz$>M{nn`O7oGaJ3&&q;M3xz+Vi*(>^4yO$`!s{d&7pbDY+GN^CuyB2oykElN9XwCDgKef5}budINsWwOmTpt216^B`%h zFjGZB&|(2fP+o0-JtRbdJ>PS0hIPt;jfPEL+g8b1mU zkKbi&wmpP=nsM*17aw`90g!2U2Z?j(mb=A$xXuvA3p1y@yTX8#(FHit->-}Aq|c}i z@VJp5?Lx!%?;V-HC!yp(1R21YT)jzOvC^RcA6`2baA;NVh<9IU@0M_QYPikv$SAbN z*^8)cnCB%g|0PKF@wPBTkV8YhaVx_H6ass}6ex*T(amCnY4~v{A+QtaY#>*{v4;H7 zlN<<1KrfQtDyK0A!QiEu^D2|JKXwd+4XGB+2v5vfepq(KHIrQ=X zz)n=i@naAbde&Fox3%^0^_h<3qkM>?u(khoQFHQPzrfaPfkQ+4yNfsMIdZVhV_~+v zhJ>kn!?EvSwmsMvQ?^p*s|j@3Iwi^k32q>d%7CGA=*@RtHY(d$>vIrHK&%$0c43>L zf?JQ^1>mD}AX=^6Zpt1)cL~5YeC)l0XGbBru(!D2?SOB8q&z zbmRx{_WsBl>)`TjD2 zd7V2x-RS0FsTs!Fg%a@h0VPiA7RmHWZSP`cZo0JIY!LHw?PHV)4GoDUc-*T|r znPfj5g=nzW+H;MPY6FOe!BcVqW-h4pEkQ&RK9Amc>eXEU9?-%H;{pC;*(6eytS>@Y z&9)gB2P%LRV#f>Arg^`K0VzuhPx9Yy(fdtC%a>a^3mm&(Wq}fe93kwmFnEy6D2)?Ufh>Q_(=wQ`^f}5&9iI_EPKBC%*quK!s zqPhz)&d}2|{46qe=v6x-zHQy(h1cAIoHz#O5uvoX!cO~!rMZ%!>4&c)ZasaKS?vvt z=tJx~VIc8ta&QE3>J(4f_7mrcGxiPb;(Hq^*mtF{QhF_->$*U%!B^#5|CRuzVsj?9 zhgCN3@q_}VOlo%}RUATheSTn{D796GM6$EoDh`w**(`<~>UAw4w{lZ{f#P=>fG<*M zp8P~h%<8a!c7c%}AFj}@hEjI&oAnAD?8hUXG$mAoG!AX5deZ@7QEXVETnL-i2+^;v zf``Rss8;f8*_F0Zn~|(3DP~~z@EYNZBXv3>d{W9Hi&BtRcUN=WwMJ@n0Bo;36JF{# z@(<7znN&mVD^s1>HY_pXKq26Z?}@IoNs|8JMwT~LM*nLgWrTndb69n~Q~Lq>f_55l zZ3OaSE0WXF>S+R?b9{Ohs84Ti)O^FC`1~SwU%GjYngCdeJ)m3cIi`UfoSz;Rc=YHI z@d9_rgm8ATNqa&X_R7R)hzf~S_U+rZ#8LTcF2>3qZrvk@r0Z9`B&ug3B+kvl1K3ho zY{LLZt`5USzKn4>m|vOhRv^$hPi;rw)>{w~cHnr1n9$Bt6#~MC zdmL%}gHDnJUAxaMJjN|u$=-mXgPWkZcQ0#6Ju7~ZQd)jRRg#hVAepzm1|bA8`-pt1 za?HvZO8;jL{<%*!;OMO~YXME)#N*nVPv86VZ15 ze17*wRopj2U~3=8X5M+cyF{p({ASAwwI9;``@V`#UZ<(yy8~=Kzu4g)a)r|B19#pi z0?FG5VhkT%l+hYH=EZnfWqEE3RNlLm}am}CE=D|lO#BwTk(t!VJr5RGN>8ycx zsDc~@4SaK@+t$kT5k8kS3-j&!`?$w3e4%P@kcNw7+Me)M@1`tb6!~!FY#?56RkGyj zQcQ;H;M#rXCxPcGsU_$0qIdj2ef!y)GC<(Xr?|?Wyz}*4wa`spIO~)sl9~u^B z=tpY?B?qT0G~W zA@N&4?XjIJ>H)dp>nX0#*;xy$zYm96N_{i`P*!6&+=BeQd;ef$vB1*mV&9m2eRG1_ zW>^Z2bXuZ+Fr?FagxB&)N@3r8sb=!oQJ02zO>D8cy1LZpGlj*EKr16U9D61Ma_-VM zD*Z`YDMUgZC8tShJTQo#;Vc9C4r;5O)9)i?!|!eYy$*?rgM*`ethCT!MniC^p2b1% z3&3VBEYTi*7#bCI19(HAS)p`bgdJxCq1M#Lin`FLjMz-Zd&wj53OdSTyOw~?fw`RO zFDobn=`7$}K4QrQC!$%TrKLAjaw`4~`z}q0?}4HU#AbPDcsRr334QmSM?+G8H;uBF z5tj`8&84_jcG#;z237-?_4%-PNw4n-(!MKk3F8Quh(K;2T9}fuB2X_4I*!M{em_=< z2-FJ6H~$d^wb%7uZY1l`DM;!G{6fT<@5p3EW=?)BIcvP`t#N3E^J>>0vMGM}sM*jC zjmR^2elHI-w*CJgeWVn&c zp|?^R4#X=e(B`5N%|N5AB#n?DO+9T97&&cDpAgeqU_2w8mxY=bl&dI_^tfb7x`?h0vUotN0GTE_M{oa4RMs?Kh1f0qP2&$bsC8= zNB9s>c=rLATRF%z>5btgbM(_B#E>c=T6bTSt;=Q*#ZLyKfHwj5j(DLY7C+5_*oQ3r zD!o09t8SYsKJ~E)d4B+a%Y)813Rtwu{hbg$)nPMl77Q8LAkubd1mjv$75r(It|#KE zDELRYiIyg$^>=M>08%i5+Lf+l`x3h7x4G`h^HZl5pwI$@f{nbe76u$xpSljb1@o;5 z`(j`$!*q1~(~#5fTIIUDj1VG zHKulcZv5*NPHFAuTbnCD!q;gLUJ#+?Ht+_dAiUZ7)OW%m76^v-mv2kJMzItaH3O4J zU6Sjd*V}S{EKhcS^-5gc@EJ(*fUH8e`R&^`ChSf2j{aGtQV3h@$%c3@hUsaF3b@Vh zzFd`Qjj^`FKJ3%MiJtu!mTaU{wcR@gRUFdd6715ntyGz52H)uKaYR*P1m#s!dXh^g z#w+)rJBGw@lc7e7$JQJILR!Gj@ZWNdF)A_ zC>gK6xjCQBdob9w3tZ7BnL7GodF;oVB8V4ka4#oK(mcoGc30Rn#johT+!%}f%xw!w z5t3#JoO-?Hb041j2VLUSp0sV6{gEemiA(P$C>w>kPQTyU{&?!uu<&wSI6}z5Onrz4 z(e&7N5di)h^9>sfYTr|HLtR2h1a)^%UFfo zr*Bz48LD)%g|r1CBvQsRGBWIYmwr4CXy7dAPiVYtv(HxTu5w|ES3vaDBQJ$2Di7>G zMhE#Fppy0&syJ^>rH&ztW!Q)=ZUeLv``!>X<>+gOddBD+J$?C#Lio-0F>k@Cq!3+f z`Skxu_8G6wiv4&L!VP8s&olHHjW%4IoXy>D{Sji1062iDivhPtBd7(S^8)kM2o3i2 zD&Q#pIZO+^V4UH?U`0MqAN!f3H(wg6DN?t9UAPIsdu$2VT+P<&(@4qEls(m@Tk?}s zf{)4Uc>%W#%$x@3sDVpMwy426NGdBWecXB-;JB0FzIf@9#7P0tRY$Jz{$@1Zafp z)1dP=8m$k)x6>OM7(5=q^C2%s=ENkFG?002BF(x|n2v9BO9%k$-?LuPhwieBzpZYD zp8G!5wo8?Y-E^q3;xz3YMFQulXus~Zi*Pq;-|}rnWUy<|EdBx#0M^DtUg1gwn}m^_ zfw`qQogAcwt5AD8#?nxk1qlzl6KGTSas2EFP%S_gM=X*92gU)+M+7=f{YqVeNaLIk z7xI;6AQnRgtU^4s>b*L=L2d_G}$~Y<_5HXgwT~ zq(+-5phf}U0;%80+G_i`1*E9eK~J=IJrr2`h7d&XV)M5lv{9^J*OJ8CHYbA`}5`Wc!!mF!%Ej;imZBcEL7ijYK*g+)Ky%jM$$b^B~)=AVP5X>>D0P&c|@pRsk1sQ9ywn;itlF3N+zToU#1+OlILg!LCXE)Zn8#;v<|}B384CW$e1lyI z1$s}5KnGTpsfYcxpS=bEtS2bMjyc9e0js9qhdj1-uR><^kom53NcvfSsr5rWy&MJq zX9I2J0M~V~>Qe(RhWzfcm;oV7H1Jt{`lWqz%|<2Ea~#+!`-XGAbv@1Bgo<$kGzAsK zvVJsU)6ucdYu_(!Ggtw8{|+Pg^V8GUm~WgVts_#so!U~maYJ2m?Z}o;NW207#*$$XZQ&e zG)%ZwQR>$IJ0mRZmvb8d)+H*0KgJp3)>^hF69YyeIrSK}nu6N^4hTerJqNDLZAUrD zGo`O5M@oA_6tR0!n!)sR<0JqOx}dGrxu;+9 ze!S+==+~?0Z;tg_%yHk_C5~RZodvDX1!9q z_RB!J;MOx#l9n?Lk|pdP#fN}$p*IAVThkd%^4d8a^Tj&_p>l05+dCL+?hjRm*u>+{1UoumyqIYS z0t|FvBtr$j52NpH(|~JEWcTj~aTZDz!@I|azBlW6BMc6WjUGYt2FhD>^fon= zIb1Cla{FhobiUQi1M?^7d@B5BfP#Z90{!hfq~qMi*s<~HA9{V}*&jcC>E;dqtb&+o zIOO^H+?o^avmoxHhJtWDwhuyEh2;?0A2xJakC*kbC=MsZb1?6-3$_=UJ;#9-AFWs) z>@<{x#2xl|o~Quq()g>pc>;8T;Y&+Px_lBf?nTaA3(39U$iU{;BtQmncnbR31M$%f zaBv18QY(MIh_b5KefCP}*{AmmP+s2#iwlI3Z9xk&GxAGfSjz$UP6e}+xV#6$BG>=9 zsAq-j;j}o~$n^B|2d1{sAWbd}x-6859mWK^oMr$%HYZXzPbl~4&9VW70^kppfV7{? zXD_Yju(?S?!eNeIn46o0*bRUG{xr5&1YqD&+}^e{C5| zPiI@t1Ypmmub&p^$bEsyPz80+7(pU5RipWhn9i{`;xrV*R*<+>%}CRT zmQSIaLhM=5<|w!j+JI@@cRcvn_aozD_9Alx66v&r_BEND9;nB36_Nh6{`BU4I&pNM zCKv&_O8NBZ))O%=I$LjtKI@KDl{k+nk`YkuYR!|$$S-1 zl~!lERsS7z;TQ83eo@Ew35*QVG@Nc;uodN}s1515t#*$Ww2JZ6UhXV+wwqb_ZL~Dn zfWJsLwa6TUR5C3gw6<9`EMcg4wzjl)YwBB~&+4h#P1fvw07?iSE^P{&Rml4Qil}4T z_`@WcNaknbEiswwj9pND%yPhFVNTO74`#3|?W;>55KTSG>=xf$Jd1uRxpyTHG;2-q zG|(~IY2u(mTdYHF1i4?x&g8CdUFfv<45afWE#sJEsyt<6`ACg%jO5GyiJIqqcZ6Iw z$Bi3}ks4QrQz$O zJxqnQip;|J^pfnr%rMg{Gz~Yzhf5lk!QpcF^b$tFGu4qv+XZ?n^+Oh@SN=RKGVgDp zoza4>DmFUt{vBQ~a@rJj{Z!zZ2GCg`6;6jh!Hfhos9V>u*U$(^&J+;BFF$W;iOD7PCn&7wtY%fej9 zAsO0z+cOeP=GH6qGI@)FBaSOEfZMTWR*BE;_P?e>#p3;$O^o8L!%x<219t?5}3Xk zpk#~!SP~CJy&Z_#j#m˙)Q?ZuW?2Y7Cpc+iDnw{ml?aP2lj;#h&?onPs7T+5aY%sE+VBEDADN z%L6HWcH8BrX{sFD9yTtsCvRYVW=p1~a zpoP?1*#4DP>183y0?W&b_}~Y$U5HoXG)~%g$Mg!mtBs#u4DD1Fp8FE3zIf%KiwVFQ zZIz$x|YfwB`?3h&C7 z3%vz(+fcWS01T&qi)gm5L}jR^2-M&n?ZNv=&+Gh+28a%L$ESTj4|8yF1=I`aL#`q% z)p7$z+v9uTJW|JtZbHH?r_KSFzu)`58_`r3E=)dry#-toG7J&>pFjkQZ8YldCNxso zk+h7bf)ky}Xxs{c-H}J~9(GNn#HG7-xa>!=0u?r2%3QF2HmuZfP8-N#7kk0q<-mdw zLvMjSowEG~o)JG8kNmC36M7Z!$umvE04T`$pVrz=r+~K=02y7+%q$669L0B5LZCVO zMFRlR#K2#C*Xe(-`qS#8SpQRCYzYE;oigFM8SF67w%gM4ReLXYQoU(-O#*=tdQfQx>s>V_*;ftF?Vj<))da zjw~oD`L)?9Aey8a|DH@H=;hZcjiNb%p(D2+X=|J9ZnU~2%5X9OEhA*p1F8p4nfS_+4X#u@>manbhno>KB;F_dUr8Jh1a2}0 znGQ24DUmyc8upp5)no!3!)?C9CQwL8rGBhnrMU$=CEK-*-vk1u8JPcOq=FkB=SRl< z0-Mm-SR5QR;A5wIwLy){TAU8qFScLXk#gYI_ZUsesHv)cTnP5wfUc|w+Vm!H8D%@y zaZ~A9|I^UYLh_~J0VwEa%AzUN1d|C(P%g5lSdAco;P!0~Wi;GyWO+vF0s=PQ!d;(} zxG%A9`IBqgUa#8gj+>)*nElaC({ri}$hv0t-Q_quR_+Bj8jOB_eLD{5mmAv5;&IAM zWSQcMOa!K59d7S-)z-j56XbVGNKr;>3q!dJDS?QOABXeC?taG9Lz*>{E{U{k6s-x!Z#185bRgEa>;k}*u=Tta9w%1|L(K$$Dn3u>-1kJFzgc5oUZlxXkJ zIaTNZmg=prOYJQ(CjjGh3m6@4m+d{S>({v(30(Z*JAV_kO0DC|z@ycK@MNWK<-TjE zsD+EcQ>WO%ba%pix6XCFnSUH2iw~NuN;J>ZTjr37n6oB;RZXO9o#w&s^2m}~fEy56 zh8`=5UZ?m2aJ3OY-~H@&-`g3F%B|!^WG3L#=h@54-~S9BIn`7J^dhozMM0AtMb64< z1Z1TVV4HCeW%>KQH-Z-A`W#6$%fO#SIt;lP>$&eZbVA>1*Y!YFtMinD({PQC3|;I5 zYAwW+w)fEZZbAmQnU>({rt=LulH_754la>VI{*55YOFd$Ie586NZ}{g#%2Z9bv>z# ze!Q+0f6vI}&cWHO0%I%DpNP@$S&$Q@gvQ3k@Un`Hka4pY%fsuWo3@`;E8d$S8Ie_= z=9!&(y0eYKkbgf6(J%0xXH#seP>^Mj^)IYlea3L^rd!p6^yq!=Xe@?|OzIKD z2hjPP00u#XG=vd2G)zZ!_#+yU^GLgX?OGso0XhUuWc-65n&O6krTCZ*;sY635I26s zM6Puf ziU%rXsugS}g$)}0V5%{12Loz$-&MS;SR4l@XZMS@U~K$^Q#i*JU*FPFTpJ(-CW6&0 zMN`vshtH}H)zvTDsxaYnd4B&|X`Gyhtoi$ejW>Z`KB2hrkVO*|$ef7{uiBZjA|96d z2GA!%0sW|raaxTG>3?*kZ)PDo zl$2CbMut4$m%EA^loG^>gv<|oRsflJMM;E}ot@nT91JVXiOfHWi=Wq>!Acxz>ywtW zVDT{lbZ*-!x?T^^f_^=Xx-GvnC>emgmh&(A86edR4?nvB z!x@_?$Ltpdu^^3QHIf^_1O;hnMj%@SdUOZj7-$w}+C9=ffEnB#cy(mW25B=X!si36 zpluS87SNACv<^cubQIa~e_AI(z&)ew73RCgQxEe<27ryBWP}`|7O?(^W>|s26Nmx3 zLiJC}5Q=l+rixy5L4W-IZz#aTc0Z1ob#)D+Z9&35}Tp# zK7()ePjzzct++5h@h4Gwb4OPEPObZOFIDBCkl5H*)m$6xqy;+(@Aae*$_!?4j-Ih1n50Aj|}Ma6soz+UFmAcs9iZtb^?;7hqj@S5ejn% zTOCd7mgZ)^AKm9WJ3Cp0g>~M&dza<>NJE3+gFbKW2W&+Sbe{)iBErHh<}HhDx>g>V zNndE4ot=GSu>>XsW!MyZt@(;|J*-(5Iwa!a`ViyvC3{&}S!p=NydS%-v!4SxQ77GI zVX4ONT!*j(+Qz%Wk%=2Z>1_EOQvcCRn1#3w!5ADD$GA9m*!o;%tGEwFRCHj`p{lS@ z9T*DaxDPmY2mB3CpGY(JSGUrr#Edsw#SnLeY5Z{e`7_7sUSQj++sYds2@eX2mp!Gk zx*Z*B#V5`vCBbaLLUvH=v*kI7VRmu{CtWz zPG&2?S(Z~$DoWARS^0|>gc~}9OAI3rK5NVFICYEAv9Yiuwm4*GW$~inEBg^9?Q32s za53fs3JMC@eGqp?`fD$rU)u?ah)8F@*b%SY?X$)-5iip7{x+aY@zKmP8BVgFrOCnay0+o~LgW!@<5f@EwAV|S~wuQL`##+Nq~k&Q6Ryl5am*{Ajn%oY6s zx9@#AY4?A;zfonViZyjzFdIo1gDFYL&2tabnz!1NLh`iXj${1Pcbp!%|FGTk(2m-4 zz58CHP*wa1)ul_*a*s=3tZ9?&sns(6C4eN7W&hPk@@DHe^F`v$4ESDp^iBBq`v`1B zyu7bYyx4l@xPSZNGPwDz>B*jQ)%n(@rlvrK%t$jGnF__AbKi;IB&U~4g;=|`9tAMU zf7Nn~Yn}KzqIj*j$yz@|a%cNI*NKUjjv>}@eeoh1-6z)FYMZxA3cJ=evr2x$pvVVa z5=hdz{7XgF3?-^VnK50C;v_}h5=x2t)t-<+4%b6+|M&H=nS3*LFjPot0HE_G~@|B7__0U=Qup zi(g~LS(t4bIZL|C2Zq~$NV9JMJ0CL)RUaqDtG^8*pFYl< zdDv_#PSDP%eqBMSeQ?)JEbgXW`41s@1kUutT^k#lnw;9m@bGb`M?a=F1S)XJNl8*G zfwH9`;o)pR-4rq0c+e;FX^t{2eRDMhesEwFW)h}=oVv^T!RhaI$Z&rIGyHNjm;nTKdl9Zg1qTTlgreNWlu712^+Px41 zle^$k8qAb*>wi_D=^Lq^q_=h6l=i@r0>H(zaiRXWNQBrH6IWekE{$p)2CaVQ`POIvkD2EALeR{D#eV9jI`HP999_aL!u;EzGCI) z?}^kDNljx2$W$}?tREA*fZtX<_dQ?sS!>f{_gx>t8(ZFVh*tgK#xL`SSR z@q4w=G(bDG$1Q#A&v=5iUcri^9*;HxJyB0itU32gnZ%kf=7F;_t4Df7oYl9}HYGV( zOZJPpT|t(Zml_52-ZI~hWlqSli+OehF;XtHU=eo$`s1qqxp~4j)sdBdK*VSx#`t%7 zag{KFPHy-5rIXFOPOmE^e#f)N32{Hqa6l3~b-A@G@8#xVMtbq`qCj?3)RuU7yV+;P z=wbVz$v$;iD_)R*#Kh4c&)n$E2Yx?x5b;RP0 zNtmE3+kB=T^>dyobw}S7Ht4?s1?00TU8gF@ zC3-vWRxN63XlR%Cs7H(4Ez@dw($A~4a%|-%!y!m#cFSY;-P7KW?_5?cRIU0u$)y}W z7=RO3Oo2x~JixknkY7sWn#K{nacpiplQ2mUDgq}`a=2v0 zyzGide9GmrrwnPkTbos5`!>t8d)Aol4O*>OCWKjs_hhEGj?kDz>#?s|O87(>21xO! zy|M_viD`OQ&p6*K8M|N8yfb@8xtXOTS5i4{ZW`Zue6=Fo=&R|I853MjQSoG5b@P^s z+wh7rN9dM>JC4txoFLT9720a7ja_$^v|@P^IO%0)a*%>D2wG+FCjtv|8&ZhyH0Uq2fk&3WWTOy&PhK4Z?XCBdrrjBj zzWf0=e8}@3qSSD7M0fep2K(TE(}>@JYQT%|poA_D?OQfoDa`A&>oH*>L@GwXP)f? zAM}B0qLx||d@!28&g7DXf(N8Eni#2HlFdM|Sx4Bk`2kB~vDu3lqtJ zp6go8{*AV&r9Mz?H_<|V**{5YK!)rvbmDh0rN3Tz{06)bNb9wE$jy>bYUCau<{44p znNE}bPfsQ5*9{XIT3ZQVayi@ug>kxEAGHpiA;H0;BpoaAG*e~GJ8 z#af`1FO{necu2S=g~H-JKx&zS6wO>WBL@=?E>0muoHatwj!pm4Z~0H_p{h|49rwle zq$FXUboDtwO)~8c=q)EMlVlyblA?@=)Y=5N1M`43Ckv^Wt*gP%a;!Q}0qb}2vSYO= zT`FT*v>2m61(lTi^IjQ`S~N8>qa+?JsSEN_mcmmAcLKCX(2Jglyzc~3ll=+G(dCV+ z05YNF$>xd$3kvw-(mWzVfZKn}$OZ!8rCV83)e%q*brJp)^$k^mMb;S=OZ&b=ty8|d&H1p}sgUthU5a$(9SrRLv>IH}+E zdb)1n-4{zH8ZLRM#epXLEm9AAV%6)5Cq=VmCeUug(ai!aCFK!lGN*_J-7B%pL8QmU zlw@Z#PclP8`piaJBQ^64i4Zlmvf)a)NMHS+=g}F~_cvHPqc%nKf-2=LlGOB}ci)%c zah5hjW}{D;pGXrYGmE}W*_?Pm)V9<-l+6jv7ycp1(oE*mi;Wq1x8gnPgtz&6n?>wD z9LK^;@`zm1%O6sclOq5edMw7k8bv{e6R0m9{V;B9Rr~)@mJ$d9rouio&wEtk+=p2= zU!HkEYeW3$aCLISd#~U*?;GO0_O;xye-otbbUJe1u9hVbUor>|5b!U5XGL9_6$>C( z0=2gTT!ly4{J=%U)r<1x!m{ViNdkSQ7@4dS8W&p#vCNfnds2%O)s(_Z+4 ze?33;G-s=}m{TjX_eUM}FNY!Io773+6} zso?|Fi)rYYOr!GUyA%{w`eqb+ps6MSVUHdv0TO|o$mxm{z}JnSbhgA#`Y8gR08hO7 z@>2`~S0^{cNYZszPAadQu?n7KgO$I$DXQ+S?4Pp9t1>dzHY+vwUz+-|`REQidz~4x zCz={Os#uT$EK??vnuZ1&&>ZzczX4=jY zc_b%hPOqNKB)=D@_MNkWU-4#@A_?i82dX!tH;I&h+7+ej*j%yyT& z+`(f{y7ZlSP8red?)@H7`JSCT_v{RZe_k$gQAU8m}8#c5M=nX4n__BCjxqt zwIg6$ynJgm{H6c>es2=BrVAJlU6Qq>zGz$q>}~O_h7CslGLLo_;+XamP~oZZ-M)r|%rRLa~40U*Rzd@28JF*kO`kOgU)+&$}rWi#|gqpjxxX zq`7e7a;{g@jHPJwgf>Fr$u9eVhI|Z4NCzvLWWg}~v;VZYgkjLIN-zvbLkew9?`ip4 zelo!78Y~WfW2#80-CR~lu*J`vO%)su-xZ;l4|u(ZpaF>pY+cWcNZ!8!F@ygNL$MFE z-Mn$bPGtDIX|7U<%cCty~vaR@;j>fjP*YV|3!@fA|EdN042Z%vbQAW-U9zLkS2+|EVh#y(j?Wb(z-va^apeKtdJP+wWH7u6JpTq-S zE9&D?#Am$s)Rk~0Q>v2_DrpNnK!1X?bY4~G)02B&toc$W!uqPG#5X5dX1r#IH6#C5 zdsi9`W&gJIROq!%n|&LVp32gbi6NA&4e4pIWGk|ahiFKM@ermMOA1+A?F>a2G1XL5 zhGdy1YhxQjk{IhW_j}#_kK_IDetEyY$8&#iVCG(a%k{f{=XIXv4K4ly;Q17weL2u` zBtZ$!(=OzVE##a5G^IyGLsvQ3c%>+KFBzPRUKsTEb8QQ+?gg#U)bXJdH8aKbLu1O59)`=SecAL07H4Cce!sBYdCO!Nj0BEev zCWti2GEw&Y^o?%#8;gpUfccj?!4kl{Ec)uO^N_JrKe&{r;YKEpx4X_1%T_?a&w&cN z)pu&R$pOb-DGFQ;W!tQ&>D4!C|CO*B9MrQNP_)U<&%cyg@}6=PoenB6s<2p;=BDAM ze@o*tYd#|$QaIL1>>oJX859^6jLFSHxP85%bFITdX1#cG=itqk&p{Ejh5^$LrOM;WG^*^# zc=#TqE@-+)SZRDs0VUUojIz1CuM8o$dVp&OFN}F(3>Mw-ppp!r-djE{=FW$zb~O^G zj??`YxSbjo`p{}``EijR?c1S1{X`LKEtM}_2b4h2Qrf%+m{lu>@ERJ0J?b7oYjKdG zLkjpC0moI6o1c5Wf3}h$M3yiUy)oqB<&~X9x0yiNPrG{;MWt~`jHBL5;r{*b3Bl9D>aq9loJ@%RChEqv_9`P;QCJn zV@lHCY2Xn@{1woq7@YF8q#y$GDk@=;GzAmfERhof?nz0FVa~Th( z_FQ9P`Aot*C*NKpy^pMaO}OMNK=0@_ppTW<&e;dDVW{7hwlz1bEQBpnkec1lMbNO0 zBVDM`3WPkJ`uh4{ z2)ym4B58JJbojVurJf*bUc{+TJ1#gvy4=qg`lDcHONROg@|(h>hYu6 z@ZcPIua*50a^)4xc*hOT{AAr9{P??*8(2KEu<7fEkeaOaDmOs7%DKV`XNSf@(t4W` z@5;CH+}c9`72NthjJw*y{J%BF4O)t-bx44?LLc_A=1|md&rL2V zfUp#Gop|RnDlo$n3$zlJq(mS#RB7p+Jac9{&Gl5LAjvdeaacw;0Epj?;2g~E1unO+iVuU)th4Ww(nwkKa1~N>IiENVd zyoF2-EUz|D%@`*rqZ@k9R#}t~LMEfNv7vR8BbA%l+H(!OkL1j5m z-TnYe$$b9sC-~t3Nm>t{MmPm63ZO$x9s`qF3!8MbQc&8w3$8cJw9prFQiAGI4z0wEnIK_eAn!u5)+3aA6ROik;dvqbk`BiS1<4gcl zo(4KvB}*W@`@@96zkaxe2+X@o)I1Nfcdf9vPJYCKgOm8`wWcV)H?rU-uH-*r38*gRbK0>aJ_Bw-^WiAW?%RnK(Kk2!9G1c(nKjUsI|~%GSHIA85aS zKwU8haOtFx=CCF3uiHEP{W+QC&2GBVbIrPi5*Aa|fKL%*z+nY9{bum~j#ctrHy&m6}8LIT3#X zd$PpK{mQp~9{@Da)#NU0opDWlY*;Z+nhFf3EjmAezMT!FMd*ezRIZ&A3FtHh_wK2F zsi}nq1<>5mW5tF64DCN)$v}B%o9zE5#v+%Y%CUTyc?49Ds*g#0E``f5EuV6fwyQHLzlNN2c_rN|YNDr2#q22apWO z*_M`+-0}y%zt!K=qU@kL@g7FCY`~cw2$Stj`snKkL`CfIB0{elp>qGr%fz9;>aOX& zO&c_TW|g4`r8|^*|63N=6$3?GR2HSSY?MH2)Whje^F=*3Q7&Go4{-TZA)l5gT65!t ztU9D{P_op9D3c_!h=NLe{teb>mTl`=fB7+rX{^D)nN&MaHRx*!7{B0wQXnN>_~_9( zexoB`YOw8%YTTEal2~Pu1T8xCk#v21Vl3E!txn?^EB^qQw!C^DWJP9IcGWJJg(xqWb9{VdMs+^-;# zFrlZ-f0%pJFoMpqu1?pnNZ~;3aYQGYYKNj0He}+$y7@&trL74qIP9lB6KYmiLW?)% zE|)%igtyom)Df#Q-4!c)?0WFQ5uj%;QG%}K*%?~MfTPup@e7!G3-h*3scAe4zh;t^ zw92m)0XExubbxQ{cuccBVRy5|iPZVBd=UGif|R^lFB)e(c{x*FU?b7|C$?;@e4z{N zi=LAVp~x?s&O)*R^8{v_{W{>4Cn-fJl`VxVDRn>9J|k6Nq~+`D(ly?s8ed>Z&^9kL zYPzr;)3ZhzBUdCASxo!#>W+XDQAd?yzwh~_)Uhg43M&`&%R2Q4|0F=`b}v3{^IC}$WHmW&!r+e&eLOK#;hEQ=x1cZ* z&_^4OS?ca!_upxb{rp$^$My7fKBX;-s$k7$xSM<2B#)Ah+*Pj1i~JZXtt9jIcX+|e z!P9_O38}jDPYrE)QcHe5^HE6rOtWKK0;gxKWVplh=F|@sqmCGdKOYL7lf@VGwpS;e zG@xn-Ev`&N{|LwNy>MUOS_?Q03sv-v2zuCnH1d58d%2YE^Uu+rjZHmMrlLu6bmjQ4 z|B?Wb*cmkJkwrcWj511c74H{#MzlQ+%|WnAy`{m5y`jD-jl#Z$GOpXUOhk)pe`TO5 z;2M>*pJuG+1T}IVby`%~d|FS3c3jiVY|RQU9^}yF4TXffZPBxOAL)+&Bk3dQJLyK# zAsMr-2Icsp2F&n6GXIo}(sQbqpz&Ew+v5%Q&R;8RTU)CA<8o zu!`B{GJqLPS?v&%*0L5w;B`0B`_ajudpi~TM5pBrBV=W99qkNqU(zPrGO1&I#{8fI z7CUF*QLbfh^{5P=p!~zpX$09g8c7bhQ7P%&KVHh7R8gupEpdFHRlNHl+%~Jkh~sO} zjxZ?3GdqEZiMr?u>4IymOkbb@%ZZ2IHNzqWy!2^r!JLoeULmw`g0`*&jtEa&lu7z3-ie{MXl^s!FUmeFluAbye;(iKqTk4YspyHPC*S-C59L&!s0 zrjbKw?j9^LRC2A*M`?7lO8X|?Y;iv%$#PQ17P3aZxAFv~>wHO_u?Fi5b@{%|MQ@U6 zs@TI^Q>CyXwhN(-BEJ>$`=?mpbkV7(*Z0~}e;0@ibe)dK&Z>1D2~f*-i=NKa#9pS5 zH?JsUv-vH+v!?1~e>FckcU3Ck+T+P|sk_WX&&4clJ^%y1pZ$WGBZI_f$ zDB%W>+=*4>vIXSDrt)#mngEh&iO&r(zal-jLECf=sIL{jV#n5`IZ|i{Z7F$)E`E5j z@(o96VVgle>2I-Gn~wE#PVjx@97%Q=cSn4qy`kmz$eY*A?c?KgPbnqM-1eP6Lax*9 z`o5NMHC4W%pmv%-3cf0F`SKG)B=3#D)2-5oG4jR{Bew_JK4G#%`R+QZ*<+%-26Upo zrc-Z;wqPWvrau>Z`FtklLmBfgXX#Wn%{IY}a`Q;Z)c4>B?<+N@oxKmjNQoL;OAMkQ z8L?FycCW#LXV4$7hQ2Jk>SmN`ZylYFvAl%TCoXsV1}rg@S$j~o`^s!SPB8Z*ws%j! zNF+)9K|zwTe)~D5rDdhr)0pnq)+>wrywE?l(fl4xl3o`t65_Q zkOL1RWWyo`X6RS5BXhSP$#xFP|BP%F5|Vm|UZI-bke+~yE-kv<9IxNVbFsr>eQ45N z!pn$Kan=i*lxw+hb3VBx6*q~+4i&NEQqaEYIwwJ;&LYb=fotavd4%el?4gmI(BdF4 z>L5Dpw=lfflBl!T6-1MDsP6g|h1>aTa0!S5`PqT$_s7|@zKU(^ko$;hVZyD~3D8g83hG$v$s?6>Td+^gPDCTTkwE9u z{mPEH({#Vxh)XtpMfm+YwYj8>7^3EzenwoIZ`B)hWKhv$+aq4_I(zw3^5T<9$;rfAiDuS04s9aQ3c zPJCVOnY)mecso_Vnw^_h;Zs-L9|S~tK!#|FKFrSW{x_jL{+~$XdxgO-k+D^K=hIs! zqFpOX^9=)g#k!e!RzJJf-%dBo8JX#qN0JYtF~cccUl++)=uLdIJ=h7?&ow0k*Poqc z_gN3AnwGRDf2~gJ<{Yk=76IQ~TkT)5^ck(~=|U#?KnWtPc05|KciGU{wny0KRl$U* zbTdAOdctY{kw|LX5Dz&=yi~=A`8wcOCMK~B9*fd0Ls;65Q`BTln&yO8r_ZUA6l3N< z?~Ixg2)%yoh~$~tFfA~t=lGQN0Ileg8Izul);3H_X7TdG73wRKDd-#FqfFw7$glL7 z*XKh8MR6A9SGcBYkHR{9A&@BOGbwIVD6Kum&mZAaJ8NN{G!74q++LM{q5Ny0?V)T= zT@C8EbRD_&SE@h3nA+ydP47IJXjTaGuH}TcFB(M>|j;CK&s$F_lzW@a7KomW+o~ft{0! z>O)VW2Za$jv9;vd=2=%>ZCk4-Sd}o z0DD%I^YcJIU1RtHazFPi-Rt%#_X`wqe|dt|gxGCzZ(ql|FlTSKRHyjKRflHowW3BP ze=qaVQxRt7tyb}?4bQIc`o~><57M*ATSx;EGDJ#!rerLfg~+o`CXed9xwy8b;9=0q z6NvYh9=b2yLR1DM8ut$Ux*N6fEvZkVbtPEjmQyr)sT1q*t&LjhF?;eAeEF^`F}NLs zb9t=bmqQ0cy-sv`qnX|C)I+gALLvQzY@1sD%Dhx}&cgMOk^Dn%$I!Oc)&DhW*G5#` zqsjlxw%?5<26a4!l&pZ@JJ?-)$~gF1;3XRw{(AyG@s!GwfsYU+qXL3YGTiy$ z+Hva5B+(Fkrq%4s_9>4zt-9(S#K38wtIYq| Date: Mon, 26 May 2025 12:26:47 -0700 Subject: [PATCH 36/40] Readme Cleanup --- README.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index f8be265..3a8222c 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@

๐Ÿฆ Follow me on Twitter โ€ข + ๐Ÿ“ง Jump to LLMs! ๐Ÿ“ง Feedback

@@ -11,23 +12,25 @@


-TorchLeet is a curated set of PyTorch practice problems, inspired by LeetCode-style challenges, designed to enhance your skills in deep learning and PyTorch. **NOW WITH LLMS!** +TorchLeet is broken into two sets of questions: +1. **Question Set**: A collection of PyTorch practice problems, ranging from basic to hard, designed to enhance your skills in deep learning and PyTorch. +2. **LLM Set**: A new set of questions focused on understanding and implementing Large Language Models (LLMs) from scratch, including attention mechanisms, embeddings, and more. +3. +> [!NOTE] +> Avoid using GPT. Try to solve these problems on your own. The goal is to learn and understand PyTorch concepts deeply. ## Table of Contents -- [TorchLeet](#torchleet) - - [Table of Contents](#table-of-contents) - - [Question Set](#question-set) - - [๐Ÿ”ตBasic](#basic) - - [๐ŸŸขEasy](#easy) - - [๐ŸŸกMedium](#medium) - - [๐Ÿ”ดHard](#hard) - - [LLM Set](#llm-set) - - [Getting Started](#getting-started) - - [1. Install Dependencies](#1-install-dependencies) - - [2. Structure](#2-structure) - - [3. How to Use](#3-how-to-use) +- [Question Set](#question-set) + - [๐Ÿ”ตBasic](#basic) + - [๐ŸŸขEasy](#easy) + - [๐ŸŸกMedium](#medium) + - [๐Ÿ”ดHard](#hard) +- [LLM Set](#llm-set) +- [Getting Started](#getting-started) + - [1. Install Dependencies](#1-install-dependencies) + - [2. Structure](#2-structure) + - [3. How to Use](#3-how-to-use) - [Contribution](#contribution) -- [Authors:](#authors) ## Question Set From 6a8cda9a4a35ef103b6342ba8d6f73e41481b04b Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 12:30:49 -0700 Subject: [PATCH 37/40] Cleanup --- README.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3a8222c..d2c691a 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,15 @@ TorchLeet is broken into two sets of questions: ## Table of Contents - [Question Set](#question-set) - - [๐Ÿ”ตBasic](#basic) - - [๐ŸŸขEasy](#easy) - - [๐ŸŸกMedium](#medium) - - [๐Ÿ”ดHard](#hard) + - [๐Ÿ”ตBasic](#basic) + - [๐ŸŸขEasy](#easy) + - [๐ŸŸกMedium](#medium) + - [๐Ÿ”ดHard](#hard) - [LLM Set](#llm-set) - [Getting Started](#getting-started) - - [1. Install Dependencies](#1-install-dependencies) - - [2. Structure](#2-structure) - - [3. How to Use](#3-how-to-use) + - [1. Install Dependencies](#1-install-dependencies) + - [2. Structure](#2-structure) + - [3. How to Use](#3-how-to-use) - [Contribution](#contribution) @@ -46,7 +46,9 @@ Mostly for beginners to get started with PyTorch. 6. [Visualize Training Progress with TensorBoard in PyTorch](torch/easy/e6/tensorboard.ipynb) [(Solution)](torch/easy/e6/tensorboard_SOLN.ipynb) 7. [Save and Load Your PyTorch Model](torch/easy/e7/save_model.ipynb) [(Solution)](torch/easy/e7/save_model_SOLN.ipynb) 10. Implement Softmax function from scratch - + +--- + ### ๐ŸŸขEasy Recommended for those who have a basic understanding of PyTorch and want to practice their skills. 1. [Implement a CNN on CIFAR-10](torch/medium/m2/CNN.ipynb) [(Solution)](torch/medium/m2/CNN_SOLN.ipynb) @@ -57,6 +59,8 @@ Recommended for those who have a basic understanding of PyTorch and want to prac 6. [Quantize your language model](torch/hard/h6/quantize-language-model.ipynb) [(Solution)](torch/hard/h6/quantize-language-model_SOLN.ipynb) 7. [Implement Mixed Precision Training using torch.cuda.amp](torch/hard/h9/cuda-amp.ipynb) [(Solution)](torch/hard/h9/cuda-amp_SOLN.ipynb) +--- + ### ๐ŸŸกMedium These problems are designed to challenge your understanding of PyTorch and deep learning concepts. They require you to implement things from scratch or apply advanced techniques. 1. [Implement parameter initialization for a CNN]() [(Solution)]() @@ -66,6 +70,8 @@ These problems are designed to challenge your understanding of PyTorch and deep 5. Build a Dense Retrieval System using PyTorch 6. Implement KNN from scratch in PyTorch +--- + ### ๐Ÿ”ดHard These problems are for advanced users who want to push their PyTorch skills to the limit. They involve complex architectures, custom layers, and advanced techniques. 1. [Write a custom Autograd function for activation (SILU)](torch/hard/h1/custom-autgrad-function.ipynb) [(Solution)](torch/hard/h1/custom-autgrad-function_SOLN.ipynb) @@ -83,6 +89,8 @@ These problems are for advanced users who want to push their PyTorch skills to t 13. Implement a Vision Transformer 14. Implement a Variational Autoencoder +--- + ## LLM Set **An all new set of questions to help you understand and implement Large Language Models from scratch.** @@ -108,7 +116,7 @@ Each question is designed to take you one step closer to building your own LLM. 16. Implement Top p Sampling atop LLM for decoding 17. Implement Temperature Sampling atop LLM for decoding 18. Implement LoRA on a layer of an LLM - 1. QLoRA? + 1. QLoRA 19. Mix two models to create a mixture of Experts 20. Apply SFT on SmolLM 21. Apply RLHF on SmolLM From 72952906b34e523281bfda63dde808a8e3195f74 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Mon, 26 May 2025 12:39:45 -0700 Subject: [PATCH 38/40] Q2 update --- README.md | 16 +- .../embeddings-q2-Question.ipynb | 126 - .../embeddings-q2.ipynb | 11715 +++++++++++++++- 3 files changed, 11671 insertions(+), 186 deletions(-) delete mode 100644 llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb diff --git a/README.md b/README.md index d2c691a..5c6a2ef 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

๐Ÿฆ Follow me on Twitter โ€ข - ๐Ÿ“ง Jump to LLMs! + โžก๏ธ Jump to LLMs! ๐Ÿ“ง Feedback

@@ -100,15 +100,15 @@ Each question is designed to take you one step closer to building your own LLM. 1. Implement KL Divergence Loss 2. Implement RMS Norm 3. [Implement Byte Pair Encoding from Scratch](llm/Byte-Pair-Encoding/BPE-q3-Question.ipynb) [(Solution)](llm/Byte-Pair-Encoding/BPE-q3.ipynb) -4. [Create an embeddings out of an LLM](llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb)[(Solution)](llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb) +4. Create a RAG Search of Embeddings from a set of Reviews 5. Implement Predictive Prefill with Speculative Decoding -6. [Implement Attention from Scratch](llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb)[(Solution)](llm/Implement-Attention-from-Scratch/attention-q4.ipynb) -7. [Implement Multi-Head Attention from Scratch](llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb)[(Solution)](llm/Multi-Head-Attention/multi-head-attention-q5.ipynb) -8. [Implement Grouped Query Attention from Scratch](llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb)[(Solution)](llm/Grouped-Query-Attention/grouped-query-attention.ipynb) +6. [Implement Attention from Scratch](llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb) [(Solution)](llm/Implement-Attention-from-Scratch/attention-q4.ipynb) +7. [Implement Multi-Head Attention from Scratch](llm/Multi-Head-Attention/multi-head-attention-q5-Question.ipynb) [(Solution)](llm/Multi-Head-Attention/multi-head-attention-q5.ipynb) +8. [Implement Grouped Query Attention from Scratch](llm/Grouped-Query-Attention/grouped-query-attention-Question.ipynb) [(Solution)](llm/Grouped-Query-Attention/grouped-query-attention.ipynb) 9. Implement KV Cache in Multi-Head Attention from Scratch -10. [Implement Sinusoidal Embeddings](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb)[(Solution)](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) -11. [Implement ROPE Embeddings](llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb)[(Solution)](llm/Rotary-Positional-Embedding/rope-q8.ipynb) -12. [Implement SmolLM from Scratch](llm/SmolLM/smollm-q12-Question.ipynb)[(Solution)](llm/SmolLM/smollm-q12.ipynb) +10. [Implement Sinusoidal Embeddings](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7-Question.ipynb) [(Solution)](llm/Sinusoidal-Positional-Embedding/sinusoidal-q7.ipynb) +11. [Implement ROPE Embeddings](llm/Rotary-Positional-Embedding/rope-q8-Question.ipynb) [(Solution)](llm/Rotary-Positional-Embedding/rope-q8.ipynb) +12. [Implement SmolLM from Scratch](llm/SmolLM/smollm-q12-Question.ipynb) [(Solution)](llm/SmolLM/smollm-q12.ipynb) 13. Implement Quantization of Models 1. GPTQ 14. Implement Beam Search atop LLM for decoding diff --git a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb deleted file mode 100644 index 412d3b5..0000000 --- a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2-Question.ipynb +++ /dev/null @@ -1,126 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Create Embeddings out of an LLM\n", - "\n", - "### Problem Statement\n", - "Your mission, should you choose to accept it, is to extract **meaningful sentence-level embeddings** using a pre-trained **causal language model (SmolLM2-135M)** on Amazon Reviews.\n", - "\n", - "You're working with a **generative language model**, but youโ€™re not here to generate Shakespeare. Instead, youโ€™ll tap into its **hidden states** to get semantic embeddings that capture the essence of a review โ€” the good, the bad, and the brutally honest.\n", - "\n", - "---\n", - "\n", - "### Requirements\n", - "\n", - "1. **Load and Tokenize Text**\n", - " - Use the `McAuley-Lab/Amazon-Reviews-2023` dataset (subset: `raw_review_All_Beauty`).\n", - " - Load ~10 sample reviews for testing.\n", - " - Tokenize them using `\"HuggingFaceTB/SmolLM2-135M\"` tokenizer.\n", - "\n", - "2. **Extract Embeddings**\n", - " - Run the tokenized batch through the model with `output_hidden_states=True`.\n", - " - Access the **last hidden layer** from `outputs.hidden_states[-1]`.\n", - "\n", - "3. **Compute Sentence Embeddings**\n", - " - Options:\n", - " - If the model uses a classification token (e.g., `[CLS]`), extract its embedding.\n", - " - For causal models (which typically donโ€™t), **average the token embeddings** from the final layer, **excluding padding tokens**.\n", - "\n", - "4. **Display the Result**\n", - " - Show the shape of your final sentence embedding tensor.\n", - " - Print at least one sentence-level embedding to verify everything worked.\n", - "\n", - "---\n", - "\n", - "### Constraints\n", - "\n", - "- โŒ Do **not** use sentence-transformers or pre-built embedding tools like `bert-as-service`.\n", - "- โŒ Do **not** generate text (no `.generate()`).\n", - "- โœ… Use only Hugging Face's `AutoModelForCausalLM` and `AutoTokenizer`.\n", - "- โœ… Exclude padding tokens when computing average embeddings.\n", - "- โœ… Ensure everything runs on `cuda` if available.\n", - "\n", - "---\n", - "\n", - "

\n", - " ๐Ÿ’ก Hint\n", - "\n", - "```python\n", - "# Run model with hidden states\n", - "outputs = model(**tokenized_inputs, output_hidden_states=True, return_dict=True)\n", - "\n", - "# Get the last hidden layer (batch_size, seq_len, hidden_dim)\n", - "last_hidden = outputs.hidden_states[-1]\n", - "\n", - "# Use the attention mask to avoid averaging over padding\n", - "attention_mask = tokenized_inputs['attention_mask'] # (batch_size, seq_len)\n", - "\n", - "# Compute masked average: zero out padding tokens\n", - "masked_embeddings = last_hidden * attention_mask.unsqueeze(-1) # broadcast mask\n", - "summed = masked_embeddings.sum(dim=1) # sum across tokens\n", - "count = attention_mask.sum(dim=1, keepdim=True) # count of non-padding tokens\n", - "\n", - "# Final sentence-level embeddings\n", - "sentence_embeddings = summed / count # (batch_size, hidden_dim)\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load Amazon Reviews dataset\n", - "from datasets import load_dataset\n", - "dataset = load_dataset(\"McAuley-Lab/Amazon-Reviews-2023\", \"raw_review_All_Beauty\", trust_remote_code=True)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Load SmolLM2-135M model and tokenizer\n", - "from transformers import AutoTokenizer, AutoModelForCausalLM\n", - "\n", - "# Load model and tokenizer\n", - "tokenizer = AutoTokenizer.from_pretrained(\"HuggingFaceTB/SmolLM2-135M\")\n", - "...\n", - "\n", - "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", - "model.to(device)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "model" - ] - } - ], - "metadata": { - "language_info": { - "name": "python" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb index 713dc6a..eb86a6c 100644 --- a/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb +++ b/llm/Create-Embeddings-out-of-an-LLM/embeddings-q2.ipynb @@ -29,9 +29,8 @@ " - If the model uses a classification token (e.g., `[CLS]`), extract its embedding.\n", " - For causal models (which typically donโ€™t), **average the token embeddings** from the final layer, **excluding padding tokens**.\n", "\n", - "4. **Display the Result**\n", - " - Show the shape of your final sentence embedding tensor.\n", - " - Print at least one sentence-level embedding to verify everything worked.\n", + "4. **Find the cosine similarity for a given keyword** \n", + " - Compute the cosine similarity between the average embeddings of the reviews and a keyword.\n", "\n", "---\n", "\n", @@ -69,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -80,28 +79,11619 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Load Amazon Reviews dataset\n", + "from datasets import load_dataset\n", + "dataset = load_dataset(\"McAuley-Lab/Amazon-Reviews-2023\", \"raw_review_All_Beauty\", trust_remote_code=True)\n", + "reviews = dataset['full'][:1000] # first 1000 reviews" + ] + }, + { + "cell_type": "code", + "execution_count": 12, "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "c:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", - " from .autonotebook import tqdm as notebook_tqdm\n", - "Generating full split: 701528 examples [00:14, 50103.12 examples/s]\n" - ] + "data": { + "text/plain": [ + "{'rating': [5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 2.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 1.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 2.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 3.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 3.0,\n", + " 3.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 3.0,\n", + " 2.0,\n", + " 4.0,\n", + " 4.0,\n", + " 2.0,\n", + " 4.0,\n", + " 3.0,\n", + " 3.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 2.0,\n", + " 3.0,\n", + " 3.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 2.0,\n", + " 3.0,\n", + " 3.0,\n", + " 4.0,\n", + " 1.0,\n", + " 1.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 1.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 1.0,\n", + " 1.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 2.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 2.0,\n", + " 1.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 2.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 2.0,\n", + " 2.0,\n", + " 2.0,\n", + " 3.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 3.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 2.0,\n", + " 2.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 1.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 2.0,\n", + " 3.0,\n", + " 1.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 1.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 1.0,\n", + " 2.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 2.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 2.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 2.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 4.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 1.0,\n", + " 2.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 1.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 1.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 3.0,\n", + " 4.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 2.0,\n", + " 5.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 2.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 1.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 1.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 2.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 3.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 4.0,\n", + " 4.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 5.0,\n", + " 3.0,\n", + " 5.0],\n", + " 'title': ['Such a lovely scent but not overpowering.',\n", + " 'Works great but smells a little weird.',\n", + " 'Yes!',\n", + " 'Synthetic feeling',\n", + " 'A+',\n", + " 'Pretty Color',\n", + " 'Handy',\n", + " 'Meh',\n", + " 'Great for at home use and so easy to use!',\n", + " 'Nice shampoo for the money',\n", + " 'Not what I thought I would be getting',\n", + " 'A little goes a long way!',\n", + " 'Just ok',\n", + " 'Good quality hair brush!',\n", + " 'Great refreshing skin care routine!',\n", + " \"Didn't do much and difficult to place and maintain on your face\",\n", + " 'Quality hair iron, works perfectly to straighten my hair!',\n", + " 'Great all natural ear swabs!',\n", + " 'Wonderful overnight cream!',\n", + " 'This really works!',\n", + " 'Nice manicure set for men or women',\n", + " 'Great combo pack. Wish I had been using this years ago!',\n", + " \"I just don't get it\",\n", + " 'Five Stars',\n", + " 'You wonโ€™t regret this purchase.',\n", + " 'nice sized !',\n", + " 'just ok',\n", + " 'not what it claims to do',\n", + " 'Moisturizing and cost efficient',\n", + " \"I'll stick to my 5 blade razor.\",\n", + " 'Ineffective',\n", + " 'Love!',\n", + " 'halo hair extensions',\n", + " 'clip rollers',\n", + " 'replacement filing discs',\n", + " 'They smell good. They are just the right size',\n", + " 'QUICK RAIN PROTECTION',\n", + " 'Good Product',\n", + " 'Oil',\n", + " 'Donโ€™t bother',\n", + " 'Not worth it',\n", + " 'Great headbands',\n", + " 'Really nice quality',\n", + " 'Nice and natural',\n", + " 'LOVE these!!!',\n", + " 'Nice colors and dries fast',\n", + " 'waste of money',\n", + " 'Quality',\n", + " 'Did the job and looked great',\n", + " 'It does work',\n", + " 'Great multi pack of bands for a great price',\n", + " 'Great for sensitive skin!',\n", + " 'Great value, stay power is good',\n", + " 'Nice scent',\n", + " 'Nice gift for a friend',\n", + " 'Great product',\n", + " 'Absolutely beautiful',\n", + " 'weird sizing.',\n", + " 'So cute',\n", + " \"Not sure what this is but it's rough\",\n", + " \"Item does what it's supposed to do\",\n", + " 'These are easy to use, but take long to put in',\n", + " 'I like the angle of this dermaplaning blade',\n", + " 'Deep cleaning as described',\n", + " 'Exactly as described super kawaii!',\n", + " 'Such a nice spray mist',\n", + " 'Not 100% sure how safe it is particularly for damaged feet.',\n", + " 'Doing the job!',\n", + " 'Hydrating!',\n", + " 'Luxurious!',\n", + " 'Good Way to Use a Face Oil',\n", + " 'Small Bottle',\n", + " 'Creamy!',\n", + " 'Leaves Skin Feeling Soft!',\n", + " 'Smells Good!',\n", + " 'Pleasant Scent',\n", + " 'Non-Irritating',\n", + " 'Refreshing!',\n", + " 'My First Scrunchie!',\n", + " 'Great for Travel!',\n", + " 'Fun Way to Try Out a New Scent',\n", + " 'Best Face Wipes!',\n", + " 'A Bit Oily',\n", + " 'Good Variety of Travel Size Skincare Products',\n", + " 'Nice Variety of Colors',\n", + " 'Comfortable Head Band',\n", + " 'Good Hand Sanitizer!',\n", + " 'Leaves Skin Feeling Soft',\n", + " 'Light Weight',\n", + " 'Soft',\n", + " 'Not The Right Target Audience',\n", + " 'Nice Fruity Scent',\n", + " 'Non-Greasy',\n", + " 'Huge Bottle!',\n", + " 'Easy to Use!',\n", + " 'Gentle!',\n", + " 'Moisturizing',\n", + " 'Leaves Teeth Clean',\n", + " \"Doesn't Irritate My Skin\",\n", + " 'Easy to Use!',\n", + " 'Soft!',\n", + " 'Great Quality',\n", + " 'Impressive!',\n", + " 'Nice Variety of Colors',\n", + " 'Great Exfoliator!',\n", + " \"Doesn't Irritate My Skin\",\n", + " \"Doesn't Sting or Burn My Eyes!\",\n", + " \"Best Peeling Kit I've Tried So Far\",\n", + " 'Fun to Use!',\n", + " 'Slight Fading of Burns So Far',\n", + " 'Looks Great!',\n", + " 'Fragrance Free!',\n", + " 'Blocks the Majority of the Light to Help You Sleep!',\n", + " 'A Little Goes A Long Way!',\n", + " 'Works great but is a tiny but bulky.',\n", + " 'great clipper cleaner',\n", + " 'Works very well',\n", + " 'Great price.',\n", + " 'Adorable and soft headbands',\n", + " 'Perfect transaction by this seller',\n", + " 'Very comfortable',\n", + " 'cheap stuff... bumpy surface, paint is ...',\n", + " 'I recommend this product to other customers',\n", + " 'Four Stars',\n", + " 'My hairdresser recommended these and I love them!',\n", + " 'good for the price!',\n", + " 'Love this Deli-Style Schar bread!',\n", + " 'Excellent Odor-free Nail Polish Remover',\n", + " 'Gorgeous',\n", + " 'Works!',\n", + " 'Got Halloween makeup kit damaged \\\\]',\n", + " 'love it!',\n", + " 'Seems good',\n", + " 'Nice lip gloss',\n", + " 'Works great',\n", + " 'Work well for light hold',\n", + " 'Works great',\n", + " 'Works great',\n", + " 'Prefer fingers',\n", + " 'Nice hair wraps',\n", + " 'Small but Works great',\n", + " 'Fun Wig',\n", + " 'Donโ€™t grab well',\n", + " 'Great oils',\n", + " 'Works great',\n", + " 'Works well',\n", + " 'Works great',\n", + " 'Great polishes',\n", + " 'Gel sunscreen',\n", + " 'Works great',\n", + " 'Works well',\n", + " 'Seems good',\n", + " 'Works well to straighten',\n", + " 'Works well',\n", + " 'Great shampoo',\n", + " 'A must have!',\n", + " 'Wow! Amazing!',\n", + " 'Obsessed and soooo moisturizing!',\n", + " 'Amazing',\n", + " 'Try them at your own risk',\n", + " 'Makeup brushes',\n", + " 'Easy to use!',\n", + " 'Worth buying! Love them.',\n", + " 'Good Product',\n", + " 'Fragrant Bouquet',\n", + " 'Five Stars',\n", + " 'Not as good as before',\n", + " \"Shoulder Length Hair - doesn't work well\",\n", + " 'Three Stars',\n", + " 'Five Stars',\n", + " 'Nice',\n", + " 'Three Stars',\n", + " 'Many many many',\n", + " 'My hair is falling out! DONโ€™T get it!',\n", + " 'Gift to a young Family member. They real like the item.',\n", + " 'Nice not thick, absorbs.',\n", + " 'Nice scent, left my hair soft.',\n", + " 'Too soft',\n", + " 'Bottom slides around',\n", + " 'A Great Product',\n", + " 'Amazing item.',\n", + " 'Big Bottle of Acetone-Based Nail Polish Remover',\n", + " 'Electric Toothbrush, Electric Flosser Are Real Deal',\n", + " 'Fantastic!',\n", + " 'Still have stretch marks',\n", + " 'Lotion-zip, too heavily scented, lip balm excellent!',\n", + " 'Typical exfolient',\n", + " 'Minimize viral risk',\n", + " 'Very Good Replacement Value',\n", + " 'Fantastic!',\n", + " 'Product to thick',\n", + " 'I left a negative review earlier',\n", + " 'This fragrance is neither offensive nor enticing; it is very subtle & lasts a few hours',\n", + " 'Typical thin and slinky silk scrunchies',\n", + " 'The cream is blue but goes on clear; it is very hydrating; looks like ยฝ a jar',\n", + " 'Thick, fragrance-free diaper cream; absorbs in about 30 seconds',\n", + " 'Good detangling comb for the right pet; handle could be thicker; my cats hate this - 2.5 stars',\n", + " 'Light-weight cream that is a bit tacky to start; slightly moisturizing once absorbed; scentless',\n", + " 'Not totally easy clean brush & tines do not pull through all the way',\n", + " 'Great medium-density blenders; flat angle is perfect for smooth applications; bad pricing on pkg',\n", + " 'Beautiful compact mirror w/high-gloss shine; nice tray; okay case all w/an inspirational verse',\n", + " 'These bandages have many uses; sticks to itself and not to skin or fur; not only tattoo grip tape',\n", + " 'I love these dense blenders & their flat angle which is perfect for smooth applications',\n", + " 'Love the angles on this blender sponge; since it is dense liquid foundation does not absorb easily',\n", + " 'Cute MOM gift but not as fragrant or impressive as I expected',\n", + " 'Gorgeous, heavy, and also fragile but must be for those w/thick long hair',\n", + " 'Packaging is heart shaped; love the colors & sponge texture; metal holder is great',\n", + " 'Love the colors in this sponge set; sponge texture is dense; metal holder is great',\n", + " 'Pretty headband but it is too slinky to stay put in my hair',\n", + " 'Love the blender sponges but I am not crazy about the brush',\n", + " 'Fragrance is subtle but lovely and floral; just enough to freshen up an area or relax to',\n", + " 'Very functional basic brush set; wish handles were longer; love the bristle color',\n", + " 'PU case really smells; brushes are okay; two brush heads frayed',\n", + " 'Wafer-thin portable soap; dissolves instantly; good lather; fragrance does not come thru on hands',\n", + " '12 supremely soft non-shedding make-up brushes with cleaner/holder',\n", + " 'Four extra large shower caps with adjustable cinch strap; best for those with lots of hair',\n", + " 'Beautiful clip but has loose applique that causes it to rattle',\n", + " 'Lightweight moisturizer that mildly moisturized my body; good for the summer - 3.5 stars',\n", + " '12 very pretty double banded headbands that fit well',\n", + " 'Marginal quality headbands; look good on; extras included are garbage - 2.5 stars',\n", + " 'Smells wonderful but suds sting my eyes & bar size is a joke and $$$$$$$$$$',\n", + " 'Supposedly has UVA/UVB sun filter but doesnโ€™t list SPF; itโ€™s lightly hydrating',\n", + " 'Excellent for applying creams, mask products,etc. but I wish the arm was stiffer',\n", + " 'Beautiful brush but it stinks like rubber tires; YUCK; price is INSANE',\n", + " 'Love the colors in this sponge set; sponge texture is light; metal holder is great',\n", + " 'Hydrating lotion but am not too crazy about the eucalyptus scent',\n", + " 'Nice set of 7 iridescent scrunchies; material can be slippery on hair',\n", + " 'Attractive scrunches with long tail; stitching shows',\n", + " 'Beautifully engraved comb; tines are a bit thick making this a bit difficult to comb with',\n", + " 'Beautiful shower cap that fits perfectly on my head but bow doesnโ€™t look good on me',\n", + " 'Gorgeous, soft quality headbands that feel great onโ€“ LOVE THEM',\n", + " 'Large\\xa0oval brush that is good for apply blush; comes w/a cinch pouch',\n", + " 'Excellent make-up brushes; beveled handles provide a good grip',\n", + " 'Roll-on fragrances are strong; comes with carry case that will hold six oils',\n", + " 'Pale orange color turns to light pink w/body heat but this is like expensive lip balm',\n", + " 'Only the lavender is pleasing to my senses; second candle is headache producing',\n", + " 'Simple headbands that loosely grip my head;wish there were more color variety',\n", + " 'Exceptionally well-made and beautiful pocket sized brush',\n", + " 'Beautiful compact mirror w/high-gloss shine; saying is one star less than special',\n", + " 'Spatulas are excellent for applying creams, mask products, etc.; brush pads good for face washing',\n", + " 'I love this iron but it does not come with gloves as specified',\n", + " 'Excellent empty glass bottle set perfect for hair coloring, essential oil sprays, etc.',\n", + " 'Super soft back brush that lathers reasonably well & cleans well but is not exfoliating',\n", + " 'Excellent empty glass bottle set perfect for hair coloring, essential oil sprays, etc.',\n", + " 'Shower caps are a bit large but they are still functional and are very attractive',\n", + " 'Narrow headbands that are not sturdy enough to keep the masks tight to the face',\n", + " 'Creamy texture; nice fragrance; takes a while to absorb but is hydrating โ€“ 3.5 stars',\n", + " 'Surprisingly this works well to remove my cream eye make-up',\n", + " 'Nice body brushes with interesting design',\n", + " 'Vegetal, messy flower balls; not sure why anyone would use this for anything but tea',\n", + " 'Very nice clip & hair tie set but clipswill break easily',\n", + " 'Very nice clip & hair tie set but clips will break easily; one broke immediately out of the package',\n", + " 'Helps to detangle my wet hair in the shower but not as good as my Heeta brush',\n", + " 'Tiny keychain bottles good for hand lotion, sunscreen, hand sanitizer, etc.; too $$$',\n", + " 'Excellent keychain carriers; 2 spray bottles dispense fine mist; flip top ones only okay โ€“ 4.5 stars',\n", + " 'Lightweight moisturizer; absorbs rapidly; leaves skin moderately hydrated; smells lemony',\n", + " 'Excellent keychain carriers; 2 spray bottles dispense fine mist; flip top ones only okay โ€“ 4.5 stars',\n", + " 'A nice selection of 6 blending sponges; similar to all others I tried',\n", + " 'Has a spicy aroma; leaves my hair nourished and enhanced my curls (see update)',\n", + " 'Kid-sized shower caps; best used to cover small serving bowls',\n", + " 'Too big & too thick for my purpose; emery surface does not last long - 2.5 stars',\n", + " 'Lightly moisturizing; has a wonderful rose fragrance; left my face silky',\n", + " 'Flexible plastic garbage with pick ends like scaled down hammer claws',\n", + " \"I'm FURIOUS - shampoo bottle DOES NOT OPEN; conditioner is nice\",\n", + " 'Versatile set of four combs that look and feel like plastic',\n", + " 'Nine cloth-covered headbands in muted 60โ€™s type colors/styles',\n", + " 'Relatively strong water flosser but reservoir is attached which makes drying it nearly impossible',\n", + " 'These sponges are great for blending & highlighting, particularly with creams',\n", + " 'Vibrant mostly shimmery colors more for women with a darker complexion',\n", + " 'This flat iron gave me mild straightening results; plates have too much space between them',\n", + " 'Cheap, flimsy, cosmetic bag that has limited hanging options and is not worth consideration in my opinion',\n", + " 'One of best volumizing shampoos for my fine wavy hair; leaves my hair fuller and curly',\n", + " 'LumaRx facial cleaning brush is like a Sonicare ElectricToothbrush for the face',\n", + " 'Must buy',\n", + " 'Made an impressionable impact.. great for teen boys!',\n", + " 'Works on every level...',\n", + " 'Perfect for skin + hair on newborns- great ethnic option!!',\n", + " 'Nice Smell',\n", + " \"Tried many brands in the past and this one is the best we've used\",\n", + " 'Pretty good for the price',\n", + " 'works for now.',\n", + " \"really liked that the product didn't have greasy or heavy feel ...\",\n", + " 'One Star',\n", + " 'Great fit',\n", + " 'Will purchase again',\n", + " 'Super Pore Strips',\n", + " 'Diamonds',\n", + " 'Great',\n", + " 'Size and price would have gotten has five stars',\n", + " 'Not so great',\n", + " 'Grumbles',\n", + " 'Do not purchase',\n", + " 'A Nice Little Intro Set',\n", + " \"A Very Good Polish, But we like Essie's Gel Couture Line even better!\",\n", + " 'Strong, Hard Working Deoderant',\n", + " 'Doesnโ€™t look natural.',\n", + " 'Five Stars',\n", + " 'Was this product used previously?',\n", + " 'Very soft and pretty!',\n", + " 'Good value and quality shower sponge',\n", + " 'These bottles are beautiful cobalt blue bottles',\n", + " 'Well Made.',\n", + " 'Works!!!',\n", + " 'Five Stars',\n", + " 'Nude #102+Buff Beige #104',\n", + " 'Gift Worthy',\n", + " 'Love the lite Vanilla Scent',\n", + " 'Giftworthy',\n", + " 'Looks FABULOUS!',\n", + " 'Terrific and makes a great baby shower gift.',\n", + " 'Worth every penny',\n", + " 'It says Organic',\n", + " 'Did not like the scent at all',\n", + " 'Not just organic',\n", + " 'Cordless Water Flosser, USB Rechargeable, 3-Mode, 4 different Jet Tips by SOOCAS W3',\n", + " 'Leave in Conditioner for Curly Hair Therapy by Royal Locks',\n", + " 'worth every penney',\n", + " 'Two tools in one',\n", + " 'Love the way it sticks to the counter',\n", + " 'Love this product !!',\n", + " 'I love this !',\n", + " 'Cute',\n", + " 'Not what I paid for',\n", + " 'Night or Day',\n", + " 'Good Glow',\n", + " 'Deep Hydration',\n", + " 'Perfect Gift Set',\n", + " 'Intense Hydration',\n", + " 'Great for Brown Skin',\n", + " 'Good for Irritated or Problem Skin',\n", + " 'Balanced PH',\n", + " 'Great Hydration',\n", + " 'Non-Greasy Shine',\n", + " 'Youth Serum',\n", + " 'Very Useful',\n", + " \"Doesn't Leave Skin Sticky\",\n", + " 'Special Care Mask',\n", + " 'Get Your Glow On',\n", + " 'Easy to Use',\n", + " 'Lightweight and Creamy',\n", + " 'Two Powerful Ingredients',\n", + " 'Lightweight and Hydrating',\n", + " 'Ideal for Curly Hair',\n", + " 'Soothes Irritated Skin',\n", + " 'Take Your Pick',\n", + " 'New Favorite!!',\n", + " 'Top Notch',\n", + " 'Truly \"Essential\" Oil',\n", + " 'Good Hydration',\n", + " 'Very Sparkly',\n", + " 'Very Hydrating',\n", + " 'Easy to Fill',\n", + " 'Smells Fantastic!!',\n", + " 'Effective Mask',\n", + " 'Gentle & Natural',\n", + " 'Hair-Loving Oils',\n", + " 'Very Hydrating',\n", + " 'Thick & Creamy',\n", + " 'A Curly Girl Must Have!',\n", + " 'Superior Hydration',\n", + " 'Ummm... No',\n", + " 'Not what was advertised',\n", + " 'Five Stars',\n", + " 'Not happy',\n", + " 'Works Well on Dry, Cracked Heels',\n", + " 'Compact, Quiet and Works Well',\n", + " 'Fantastic for everyday use',\n", + " 'Poor design',\n", + " 'Adorable and so soft',\n", + " 'WAIT AND CHECK REVIEWS',\n", + " 'Best Ever',\n", + " 'Dry & crumbly',\n", + " 'Do not waste time or money',\n", + " 'Buttery smooth with beautiful pigments',\n", + " 'Band too wide and stiff',\n", + " 'Band too wide',\n", + " 'This is not wj',\n", + " 'Impressed!',\n", + " 'Two Stars',\n", + " 'Crap',\n", + " 'Poor eye cream, acceptable lip balm.',\n", + " 'Nice',\n", + " 'Works for most people that like strong smells',\n", + " 'Flawless Coverage',\n", + " 'Curling iron doubles as flat iron! love it!',\n", + " 'hard to find nail polish color - black',\n", + " 'Comfy',\n", + " 'Doesnโ€™t freeze well',\n", + " 'Fun wigs for our wig & wine party',\n", + " 'Loving the way it makes my hair shine.',\n", + " 'OMG Holy ๐Ÿฅฅ Coconut Hydration!',\n", + " 'Just Sit Back, Relax, and Chill with this Pair of Stainless Steel Thingamabobs! โ„๏ธ๐Ÿฅ„',\n", + " 'I Couldnโ€™t Be More Impressed! ๐Ÿ’–',\n", + " 'Sweet Scents and Pamper-Worthy Products! ๐Ÿ›',\n", + " 'These Masks Leave My Hair So Smooth and Shiny! ๐Ÿ‘ฉ๐Ÿผ',\n", + " 'Do the Elasticized Twist! ๐Ÿช',\n", + " 'Great for Scooping Up and Spreading Around Globs and Dollops of Face Stuff!',\n", + " 'Convenient, Discrete, and Easy To Use',\n", + " 'A Nicely Varied Shade of Jade!',\n", + " 'Bee-Powered Skincare at its Finest! ๐Ÿฏ',\n", + " 'Such a Brightly Patterned Variety! ๐ŸŒพ๐ŸŒป',\n", + " 'A Refreshing Botanical Cleanser! ๐Ÿงก',\n", + " 'What a โ€œCheekyโ€ Product! ๐Ÿ‘',\n", + " 'Tea Tree Cleanliness Thatโ€™s Perfectly Sized! ๐ŸŒณ',\n", + " 'Stainless Steel Perfection!',\n", + " 'Pearlescent Purple Pretties! Backing Cards Bent',\n", + " 'Soft, Lightweight, Nice to Have on Hand! ๐Ÿ›',\n", + " 'Nourishing, Organic Cream from California!',\n", + " 'Pale Pink Perfection! ๐ŸŒธ',\n", + " 'Each Portable Pouch Contains a Clear, Floral-Scented Gel!',\n", + " 'The Fabric Tends to Ripple Somewhat',\n", + " 'Hydrating and Delightfully Scented Bits of Eye Gold! ๐Ÿคฉ',\n", + " 'A Great Way To Start the Day! ๐ŸŠ๐Ÿ’ฆ',\n", + " 'Delightful Set of Rose Quartz Rollers!! ๐Ÿ’ž',\n", + " 'Finally, a portable hairbrush for my hair.',\n", + " 'Awesome',\n", + " 'Love it',\n", + " 'Good product',\n", + " 'Great!',\n", + " 'Very large and heavy',\n", + " 'My favorite.',\n", + " 'Good product',\n", + " 'PERFECT',\n", + " 'soft!',\n", + " 'pretty',\n", + " 'very pretty',\n", + " 'Waterproof!',\n", + " 'Dries quick!',\n", + " 'Perfect for removal',\n", + " 'Check these nails out!',\n", + " 'Been obsessed with gels ๐Ÿ’…๐Ÿป',\n", + " 'Good for your pores ๐Ÿงผ๐Ÿงผ๐Ÿงผ',\n", + " 'Softness again!',\n", + " 'Awesome foundation!',\n", + " 'Five Stars',\n", + " 'Germa Manteca Ubre Plus',\n", + " 'Work great. Fair price.',\n", + " 'Good product',\n", + " 'Five Stars',\n", + " 'these are great',\n", + " 'safe step',\n", + " 'Better than the originals',\n", + " 'Canโ€™t beat this deal!',\n", + " 'Great bag',\n", + " 'Good...But Not My Favorite',\n", + " 'A Reasonably Priced Product That Works Very Well',\n", + " 'Perfect for My Dry, Sensitive, Aging Skin',\n", + " \"A Good Aloe/Hyaluronic Gel Cream-(but the jar isn't full?)\",\n", + " 'Delivers Results I Rarely See w/Other Like Products',\n", + " 'High Quality Product That Delivers High Quality Results',\n", + " 'Deeply and Gently Cleans Pores',\n", + " 'Crisp and Refreshing!',\n", + " 'An Amazing Duo!',\n", + " 'FABULOUS Brush!',\n", + " 'Pamper Yourself...',\n", + " 'Fantastic Cream!',\n", + " 'Nice Leave-In w/ A Great Scent!',\n", + " 'I LOVE What Easydew Does For My Skin!',\n", + " 'SO Many Uses For Both Oils! I LOVE Them!',\n", + " 'Not The Right Mud Mask For Me',\n", + " 'Patches Work Well...Not a Huge Fan of the Roller',\n", + " \"Good Results, Good Men's Lotion\",\n", + " 'Softens, Smooths and Soothes Skin',\n", + " 'Same Results as Dunking in a Bowl of Water',\n", + " 'Follain Does What It Promises To Do',\n", + " 'Lightweight, Refreshing and Wonderful',\n", + " 'Never Knew My Feet Could Be So Soft!',\n", + " 'Took Care of My Brassy Hair the First Time I Used It!',\n", + " 'Nice Formula!',\n", + " 'So Fabulous!',\n", + " 'Excellent Purchase',\n", + " 'Looks cute !!',\n", + " 'Not for thick hair',\n", + " 'Not for thick hair',\n", + " \"Gives soft lips but doesn't absorb well\",\n", + " 'These are very nice masks that do exactly what they claim.',\n", + " 'Got thick hair? Get these scrunchies!!',\n", + " 'Decent products but over-priced and over-packaged',\n", + " 'Please put the directions on the bottle!',\n", + " 'Lasts and Lasts',\n", + " 'Great Glosses!',\n", + " 'Not what I received',\n", + " 'Salux Wathclothes',\n", + " 'Best Hair Serum',\n", + " 'Junk',\n", + " 'Four Stars',\n", + " 'Five Stars',\n", + " 'Five Stars',\n", + " 'Five Stars',\n", + " 'This product is simply over priced. Have no idea ...',\n", + " 'Durable cute retro ๐Ÿ˜',\n", + " 'Love it',\n", + " 'Work well and are a good size.',\n", + " 'Used daily',\n", + " 'Hair claws',\n", + " 'Great product at a Great Price!',\n", + " 'Pretty cheap quality.',\n", + " 'Best Dry Shampoo',\n", + " 'so luxurious',\n", + " 'OK',\n", + " 'Effective and taste good',\n", + " 'Great shave',\n", + " 'Four Stars',\n", + " 'Blades',\n", + " 'exactly what i ordered + happy with my purchase',\n", + " 'Great for Doterra OnGuard',\n", + " 'A bit small.',\n", + " 'Very sturdy!',\n", + " 'The curls do not revert to original pattern after wetting',\n", + " 'Three Stars',\n", + " '100% happy thank you :-)',\n", + " 'Not what I expected',\n", + " 'Cheap product',\n", + " 'What a Blessing',\n", + " 'Such a lovely fragrance',\n", + " 'Left my hair dull',\n", + " 'Huge',\n", + " 'No',\n", + " 'My favorite eyelash and eyeliner kit ever!!!!!',\n", + " 'Two Stars',\n", + " 'Satisfactory',\n", + " 'The inner elastic needs to be covered to avoid irritation when wearing',\n", + " 'Will purchase again.',\n", + " 'Best mousse ever made!',\n", + " 'This is so Great !!!',\n", + " 'Great product',\n", + " 'Five Stars',\n", + " 'Great product...Styles and Volumizes Your Hair',\n", + " 'WOW!!',\n", + " 'LOVE THESE!!',\n", + " 'Great with the Halloween display.',\n", + " 'Ehh. Foil with soaked cotton balls accomplished the same ...',\n", + " 'Great dupe for C Thirbury',\n", + " \"It does work, but doesn't come off that easy. Makes my eyelashes a lot longer.\",\n", + " 'If you are good working with powders this is for you',\n", + " 'warm hat',\n", + " 'Son liked!',\n", + " 'Very nice!!',\n", + " 'Softer hair',\n", + " 'Best for sensitive eyes',\n", + " 'This is a must in every ladies makeup kit.',\n", + " 'Wish Almaty would bring this product back',\n", + " 'Not impressed',\n", + " 'A lil runny',\n", + " 'Recommend',\n", + " 'Variety of colors',\n", + " 'They were too frizzy',\n", + " 'Value and quality.',\n", + " 'My favorite makeup!',\n", + " \"over priced, over hyped, doesn't work\",\n", + " 'Too oily',\n", + " 'Drying my hair',\n", + " 'Overpriced and no result',\n", + " 'Not a fan',\n", + " 'Easy to use',\n", + " 'Nice gift set',\n", + " 'The quality is so bad',\n", + " 'Shouldnโ€™t sell for money',\n", + " 'Awesome Product',\n", + " 'buy it',\n", + " 'Great brush for cats and small dogs.',\n", + " 'Fairly well made but very small',\n", + " 'Five Stars',\n", + " 'Fabulous',\n", + " 'Great buy',\n", + " 'Great value for your bucks',\n", + " 'Two Stars',\n", + " 'Complete scam',\n", + " 'Meh',\n", + " 'Works well',\n", + " 'Do not buy smells terrible',\n", + " 'Not a good product',\n", + " 'Use it after touching raw meat when cooking.',\n", + " 'Loud but effective',\n", + " 'An Inexpensive Way to Whiter Teeth',\n", + " 'Light and yummy citrus moisturizer',\n", + " 'Amazing product',\n", + " 'Very cute',\n", + " 'Help your eyelashes come back faster will let you know how it works after 8 weeks',\n", + " 'Four Stars',\n", + " 'Two Stars',\n", + " 'Two Stars',\n", + " 'but seem to be very good quality and the case is beautiful',\n", + " 'Get it straight',\n", + " 'Color matcha',\n", + " 'Betty Dain rocks!',\n", + " 'Too oily for me.',\n", + " '.',\n", + " \"Don't waste your money\",\n", + " 'It fills a need in my collection',\n", + " 'Absolutely my favorite!',\n", + " \"Don't waste your money\",\n", + " 'One Star',\n", + " 'Five Stars',\n", + " 'Not even close.',\n", + " 'Good for the price.',\n", + " 'Just what I needed',\n", + " 'Love',\n", + " 'I absolutely love this stuff',\n", + " 'buy these',\n", + " '... moderate pain relief and the texture and scent are nice.',\n", + " 'Great stuff',\n", + " 'Great!',\n", + " 'Cute necklace',\n", + " 'Works Just as Advertised',\n", + " 'Moisture & detangles',\n", + " 'Three Stars',\n", + " 'Five Stars',\n", + " 'Buy These!',\n", + " \"It took a lot of scrubbing to get off - I think that's a good thing!\",\n", + " 'Three Stars',\n", + " 'Need more for bedrooms',\n", + " 'Five Stars',\n", + " 'Five Stars',\n", + " 'Five Stars',\n", + " 'Plenty of Glitter',\n", + " 'connectors work great.',\n", + " 'Like magic!',\n", + " 'It works',\n", + " 'Holds up well',\n", + " 'If I could give a zero I would',\n", + " 'Too large to use properly. Not good quality',\n", + " 'ABSOLUTELY STUNNING LASHES',\n", + " 'A great Christmas gift!',\n", + " 'Five Stars',\n", + " 'Save your money',\n", + " 'Nothing Great Here',\n", + " 'Kept Coming Apart',\n", + " 'Does It Really Do Anything?',\n", + " 'Avoid This',\n", + " 'Miracle in a bottle',\n", + " 'Calling this \"Virtually indestructible\" should be a crime.',\n", + " 'Five Stars',\n", + " 'Amazing, sums it up',\n", + " 'Four Stars',\n", + " 'Five Stars',\n", + " \"Smells amazing. Doesn't seem to dry my skin\",\n", + " 'If you have bangs forget about it',\n", + " 'Not For Lefties.',\n", + " 'Still good, but a bit dry.',\n", + " 'saves us $',\n", + " 'Good products',\n", + " \"You'd be better off using a lawnmower!\",\n", + " 'My son said the smell is awesome!',\n", + " 'Five Stars',\n", + " 'Teens/preteen loved them',\n", + " 'Love the quality',\n", + " 'Works perfectly, requires two pumps for normal amount of mouthwash',\n", + " 'Save you money',\n", + " 'Tiny tiny applicator',\n", + " 'Brown hair shampoo & conditioner',\n", + " 'Contains a poisonous toxic chemical formaldehyde',\n", + " 'watering eyes running nose headache',\n", + " 'Does the job',\n", + " 'Excellent product',\n", + " 'Love it',\n", + " 'Saved the day!',\n", + " 'Not great',\n", + " 'Love it',\n", + " 'Five Stars',\n", + " 'Worth it',\n", + " 'Need it',\n", + " 'It actually works!',\n", + " 'very nice smell',\n", + " 'Love the fragrance',\n", + " 'works great.',\n", + " 'Not for fine hair',\n", + " 'Great product. Have purchased before',\n", + " 'Color is very inaccurate',\n", + " 'Not practical',\n", + " 'The best',\n", + " 'Easy',\n", + " 'Too big',\n", + " 'Liquid works best for me',\n", + " 'Good for the price.',\n", + " 'These are pretty small',\n", + " 'Awesome value',\n", + " 'Loving it....made a noticeable difference!',\n", + " 'Robot in disguise?',\n", + " 'Great product',\n", + " 'A great make-up remover!!!',\n", + " 'Great for heat embossing!',\n", + " 'It works ok. On my mother it is very ...',\n", + " 'Five Stars',\n", + " 'Bad chalk',\n", + " 'a ladies must',\n", + " 'Five Stars',\n", + " 'Great toothbrushes',\n", + " 'Best Bamboo Toothbrushes',\n", + " 'Strong chemical type scent',\n", + " 'Good with coarse donkey hair',\n", + " 'Nice for dry, cracked heels',\n", + " 'Pulls and tangles long hair',\n", + " 'Seems to work well, no weird residue left behind',\n", + " 'Thick and good at removing grime',\n", + " 'Good scrunchie for ridiculous price',\n", + " 'Totally painless, needs a battery, but works as it should',\n", + " \"Doesn't irritate my sensitive skin. Creamy, requires very little to use. No actual change to wrinkles.\",\n", + " 'Does a nice job when alternated with other shampoo every few days',\n", + " 'INFERIOR QUALITY. AUSSIE FREEZE MUCH BETTER INVESTMENT.',\n", + " 'Exactly what it described to be and smells very good.',\n", + " 'The color is way off from the description',\n", + " 'You get ONE PIECE. Important to realize',\n", + " 'Better for dogs than cats',\n", + " 'Ok. Soft, not a lot of shine on their own, they are ok',\n", + " 'Nice texture',\n", + " 'Great gift',\n", + " 'Love almay powder',\n", + " 'Worked well, but came off quick in the heat',\n", + " \"Best deodorant I've tried -- and I'm old enough to have tried a LOT of them ...\",\n", + " \"The best of this type I've seen ...\",\n", + " 'Extremely Overpriced for What You Get and Dubious Claims',\n", + " 'The Granite Mats Are Truly the Best Mats',\n", + " 'Lather Up!',\n", + " 'Looks like cheap doll hair.',\n", + " 'No over powering scent. Holds hair well in all weather',\n", + " 'DONT BUY!',\n", + " 'Love',\n", + " 'Not the 4 colors advertised',\n", + " 'THICK and HEAVY!',\n", + " 'Sturdier than they look - Updated',\n", + " 'quick delivery Will recommend to all of my family and',\n", + " 'Love These Soap Sacks!',\n", + " 'IT WORKS',\n", + " 'No dif than all other clear coats',\n", + " 'nozzle wont work',\n", + " 'Left on 5 mins only - per instructions (and new highlights) - didnt work',\n", + " 'Love!',\n", + " 'Way too yellow - not as moist',\n", + " 'Altaire Paris Ceam',\n", + " 'Love love love',\n", + " 'Comfortable',\n", + " 'So nice',\n", + " 'eye shadow',\n", + " 'Other canned bean sprouts I bought had no label distinction ...',\n", + " 'Very sharp',\n", + " 'Great for my sensitive skin, great scent',\n", + " 'I used after shampoo or if the weather its humid, I leave on .',\n", + " 'Handy convenient pack of tweezers',\n", + " 'Good clips',\n", + " 'Great color for hazel eyes.',\n", + " 'Didnt care for this product',\n", + " 'Great for the price',\n", + " 'Poor quality',\n", + " 'Not all that effective but my boy loves it.',\n", + " 'Definitly worth the price',\n", + " 'Love love love this nail polish',\n", + " 'Has made bathing our 3 pound shih tzu A LOT ...',\n", + " 'Classy',\n", + " 'Good quality',\n", + " 'Do not recommend',\n", + " 'lightweight, natural coverage, dewy, has goodly amount of sunscreen',\n", + " 'nice formula, feels good, absorbs well, effective. This is my 2nd container. Love GoMay',\n", + " 'lasts all day, removes easily, actually lengthens, doesnt irritate my eyes, budget friendly option',\n", + " 'highly versatile, well made, effective shower cap. Fits my large head, and all my hair',\n", + " 'excellent coverage, non cakey, doesnt settle into lines, a tad warm for fair, cool skin',\n", + " 'creamy semi matte finish, bold, bright pop of color, fades w/ drink & food, smudges',\n", + " 'surprisingly very nice gift assortment, well packaged, definitely gift worthy',\n", + " 'great cat toys, not bad for hair lol Would like them if they fit my wrist',\n", + " 'GLOW recipe for brightening, repairing, hydrating. Decent wipe for hands, feet, wherever',\n", + " 'hydrating toner adds moisture and other nourishing ingredients.',\n", + " 'gentle, moisturizing, intense- great for dry skin, revitalizing, healing, luscious',\n", + " 'thin, light weight lotion that is perfectly rich. Makes for instantly supple, radiant, soft skin',\n", + " 'so incredibly soft, stays in place, attractive, high quality, I AM IMPRESSED',\n", + " 'travel sized bottle will provide many applications, works well, even better as day goes on',\n", + " 'very light, absorbs well, works well alone or over other skin care products',\n", + " 'This is a gommage. It is meant to clump/form bits. Apply to dry face, massage, rinse. SOFTNESS!',\n", + " 'Woah, I have eye lashes! also, does not irritate my sensitive eyes',\n", + " 'dry rot dropper, my bottle of oil arrived rancid- had to be trashed',\n", + " 'Irritated eyes and no added effect. Not one iota of difference on my lashes.',\n", + " 'glowing glassy skin. NIACINAMIDE (2%), ADENOSINE (.04%) & PEARL EXTRACT',\n", + " 'wipes are ok. Convenient, non irritating, effective at quick clean up',\n", + " 'excellent ingredients, could use more packaging info, works well w/ shamp & conditioner',\n", + " 'TRY THIS! test on FACE for match not hands, evens out skin tone, not for dry skin',\n", + " 'Made in USA. Smells fresh and energizing, nice lather, rinses clean',\n", + " 'edit: 1st one stuck, all the rest wouldnt stay in place even laying down!',\n", + " 'skin feels instantly hydrated, soothed, supple looking. EGF',\n", + " 'hydrating gentle creamy foam, cleanses & rinses well, includes EGF for skin repair',\n", + " 'excellent at evening out rosy skin, great smelling tinted mineral sunscreen, great as primer',\n", + " 'creamy, effortless application, does not irritate my sensitive eyes',\n", + " 'solid balm to oil cleanswer melts away gunk of the day; soothing & hydrating',\n", + " 'Softest hands ever, lightly scented w/ lemongrass oil, lemon oil, orange oil, rosemary',\n", + " 'gentle, non irritating, hydrating, creamy-ish lather leaves skin clean and soft',\n", + " 'dry oil, dont need much, contains retinol so beware of skin sensitivity/sun exposure',\n", + " 'Aromatic bars of \"Soap Shields\" that gently scrub & cleanse',\n", + " 'weightless, non tacky, fully absorbs quickly, NO added fragrance, no scent',\n", + " 'dense mask, smells good, great ingredients; my tin is dented/no protective seal',\n", + " 'very gentle effective cleanser for my sensitive dry skin',\n", + " 'just like mousse or shaving cream, but is a soap for body',\n", + " 'refreshing, hydrating, basic, budget friendly, add to self care themed gift',\n", + " 'gentle, cool, gel like; give it time- functional cosmetics',\n", + " 'calms my skin, redness reduction with my rosacea, lightweight and hydrating',\n", + " 'skin loving, skin calming, skin repairing ingredients',\n", + " 'dry soft granular \"scrub\"/mask, just add water/hydrosol. Directions for use on Face',\n", + " 'light, liquidy, quick absorbing, no added fragrance (but contain E.O.), gentle, great post shower',\n", + " 'lightweight but rich, pump style tube container, great on neck and hands',\n", + " 'gentle cleansing, lots of suds, leaves skin clean but not parched, great for travel',\n", + " 'non greasy, high moisture, makes skin soft, supple, comfortable feeling',\n", + " 'seems promising, will continue to update (added Edit below)',\n", + " 'excellent sunscreen with skin loving ingredients, broad spectrum, great little container',\n", + " 'clean brushes every time',\n", + " 'like a black body suit is being painted onto each lash; zero eye irritation, easy to wash off',\n", + " 'lightweight, budget friendly, soothing cica cream, use all over',\n", + " 'this is a medium tint- definitely gives sun kissed glow, absorbs well, hydrates, non greasy',\n", + " 'LOVE! super gentle manual exfoliation & chemical peeling product; deep cleans pores; brightens',\n", + " 'scent is too much for me on this one, but there other ones are awesome; great nourishing scrub',\n", + " 'great for travel or whenever, also BPA food grade material- opens up options for use!',\n", + " 'sharp, long plade, short handle, slices hair off easily',\n", + " 'great tool in helping to maintain a healthy mouth',\n", + " 'easy use, comfortable, could have longer nozzle',\n", + " 'deplaner wand= razor handle. Just use a razor',\n", + " 'not salon straight, but natural straight looking results',\n", + " 'cold jade feels good on face',\n", + " 'Great product',\n", + " 'Very Natural',\n", + " 'Really Nice!',\n", + " 'Great for My Neck',\n", + " 'I dare a company to send me a curler that works better!',\n", + " 'Great quality',\n", + " 'Smells great!',\n", + " 'Recommend!!',\n", + " 'Not too thick',\n", + " 'Worth it',\n", + " 'Precise and long lasting',\n", + " 'Did not work',\n", + " 'I like the hair I hate the term dreadlocks I like lovelocks better.',\n", + " 'I really like Willie Morrows products and this comb is excellent.',\n", + " 'Excellent, party on brothers and sisters.',\n", + " \"it's more of a spinner than a shaker.\",\n", + " \"You don't need a leather strap for this razor.\",\n", + " 'This girl is head and shoulders over most mannequin heads.',\n", + " 'Keeping your tongue clean makes your food taste better.',\n", + " 'I hate the term dreadlock, but I love these accessories.',\n", + " 'OK for a little.',\n", + " 'You get 40 Lashes.',\n", + " 'More than just a face painting kit',\n", + " 'Poly want some gel nails?',\n", + " 'Heart to heart from finish to start',\n", + " 'Take a tip, these are some nice tips.',\n", + " 'This thing really sucks, your blackheads really well.',\n", + " 'Fun to wear and headband very Afrocentric.',\n", + " 'EZ on EZ off Face Paint',\n", + " \"Awesome dental kit for those who don't like flossing...\",\n", + " 'works great for haircuts',\n", + " 'works for what I needed',\n", + " 'weightless',\n", + " 'comfortable',\n", + " 'so soft',\n", + " 'Five Stars',\n", + " 'My Brushes Are Like New Again!',\n", + " 'Not as easy to use in my own hair in the beginning.',\n", + " 'Works great for me.',\n", + " 'These are great. I love the wedge-shaped ones the best but they are all nice.',\n", + " 'Shocked at how well it worked.',\n", + " 'Not impressed with the quality.',\n", + " 'Love all the sizes but I love the 6mm best.',\n", + " 'Beautiful colors.',\n", + " 'Nice kit. Love the cutters and gemstones.',\n", + " 'Put the container in something before opening. The little pieces stick to the top and go everywhere.',\n", + " 'Not to greasy and not an overpowering scent.',\n", + " 'I think I clicked on the wrong polish.',\n", + " 'Instructions not included.',\n", + " 'These are just too stinkin cute!',\n", + " 'Not impressed with the pouf ball, the rest of the set is nice.',\n", + " 'It is very cute in your hair.',\n", + " \"I haven't found a place to buy replacement heads when needed.\",\n", + " 'Works great!',\n", + " \"It is soft but doesn't work any better than other mitts.\",\n", + " 'Makes the face fill fresh and clean.',\n", + " 'No instructions!',\n", + " 'Latch hook included.',\n", + " 'No difference in my skin. I will use the jade in something else.',\n", + " 'These work great!',\n", + " 'Bright red. Chapped my lips.',\n", + " 'Will reorder',\n", + " 'Five Stars',\n", + " 'Nice basket of bath bombs',\n", + " 'Works great!',\n", + " 'Love it',\n", + " 'Works great',\n", + " 'Good primer set',\n", + " 'Five Stars',\n", + " 'Just a few drops morning and evening make a difference',\n", + " 'Allgirls love makkeup.',\n", + " 'Five Stars',\n", + " 'This bag was smaller than i expected but still useful. Attentive seller',\n", + " 'Peel off.',\n", + " 'Super Cute but Breaks Easily',\n", + " 'Cute but Not Really',\n", + " 'Beautiful Nails',\n", + " 'Great Lashes and Liner',\n", + " 'Great Priming Set',\n", + " \"Beautiful but isn't strip but instead string.\",\n", + " 'Great Product',\n", + " 'Made for people with thick hair!',\n", + " 'Refreshing and Smoother Looking Skin',\n", + " 'Easy to Use',\n", + " 'Great Resin Decorating Sampler and Tools',\n", + " 'Beautiful Colors',\n", + " 'Great Value!',\n", + " 'Great for Washing Hands',\n", + " 'Mixed Feelings',\n", + " 'Great Set',\n", + " 'Very Nice Set!',\n", + " 'Fantastic Value!',\n", + " 'Great deal',\n", + " 'I love this product.',\n", + " 'Painless and Perfect for Eyebrow Shaping',\n", + " 'NIce bands',\n", + " 'Good wig',\n", + " 'Nice set',\n", + " 'Very pretty',\n", + " 'Great for parties',\n", + " 'Nice set',\n", + " 'Nice set',\n", + " 'Lovely',\n", + " 'Nice set',\n", + " 'Nice mascara',\n", + " 'Nice set',\n", + " 'Great set',\n", + " 'Good nail files',\n", + " 'Pretty colors',\n", + " 'Very lovely',\n", + " 'Great set',\n", + " 'Pretty',\n", + " 'Nice flat iron',\n", + " 'The best razor ever!',\n", + " 'Very helpful product',\n", + " 'Just as pictured. Font could be nicer',\n", + " 'Nice perfume scent instead of the harsh chemical smell',\n", + " 'I got this for my son who is obsessed with ...',\n", + " '... and he is always looking for the newest and best equipment. Tattoo machines are an important part of ...',\n", + " 'I am always searching for the newest and the best cleansers and treatments',\n", + " \"I've been using this for about a week and honestly I haven't seen an improvement in my complexion or anything fancy but this is\",\n", + " 'I am always on the lookout for the best products. This brush is definitely a must have',\n", + " 'This has two of my favorite things, blackberries and organic ingredients',\n", + " 'Not only is this shampoo organic and not loaded with sulfates and parabens but it has an amazing smell. Almost like a sweet ceda',\n", + " 'Amazing service',\n", + " 'Masculine scent',\n", + " 'Waste of money',\n", + " 'It Really Worked',\n", + " 'Nice Enough',\n", + " 'Fabulous Headbands',\n", + " 'My hair is flat!',\n", + " 'Excellent Tattoo Aftercare Product',\n", + " 'SUPERB FACIAL SERUM',\n", + " 'An excellent glove brush',\n", + " 'Love the look but this is some overpriced POOR quality item!',\n", + " \"Don't waste money\",\n", + " 'Easy to use',\n", + " 'This dye is lovely both in color and ease of use.',\n", + " \"Didn't work for me, but no damage\",\n", + " 'Not very magnetic',\n", + " 'Good tools',\n", + " 'Perfect damage-free hair tie!',\n", + " 'Decent set of brushes',\n", + " 'Just ok.',\n", + " 'Average product',\n", + " 'Very invigorating!',\n", + " 'Not sure yet.',\n", + " 'This stuff is your friend!',\n", + " 'Extremely happy with this',\n", + " 'Happy with this',\n", + " 'Very happy with results',\n", + " 'Very nice brush',\n", + " \"THE BEST BRONZER I'VE EVER USED\",\n", + " 'Top quality cleanser',\n", + " 'Not my favorite blonde',\n", + " 'Not sure if this works.',\n", + " 'Awesome product',\n", + " 'Smells great! Works ok.',\n", + " 'Great for hair cutting',\n", + " 'Excatly as described but...',\n", + " 'A little bit goes a long way!',\n", + " 'Stress Killer!!',\n", + " 'Perfect costume/cosplay wig',\n", + " 'Still had the smell',\n", + " 'Perfect',\n", + " 'Bonitas pero pequeรฑas',\n", + " 'Makes your lashes really long when it works.',\n", + " 'Really cute headbands!',\n", + " 'Easy to use with fast results',\n", + " 'Comes off easily',\n", + " 'Smells amazing and hypoallergenic.',\n", + " 'They are large and strong enough to hold long thick hair.',\n", + " 'Very moisturizing, but not greasy!',\n", + " 'Itโ€™s great for testing new hairstyles!',\n", + " 'Practice makes perfect',\n", + " 'Packaged so nicely and smell lovely!',\n", + " 'Sweet with a little bit of spice!',\n", + " 'The perfect set for your hair!',\n", + " 'Sanitizes without drying out hands!',\n", + " 'Easy to apply, does not irritate.',\n", + " 'Makes your skin feel baby soft!',\n", + " 'Beautifully scented and sprays on like a mist!',\n", + " 'Feels so refreshing!',\n", + " 'VERY nice, seems to be working, and a little goes a long way',\n", + " 'Truly Seamless, works well on wet and dry hair',\n", + " 'Pretty but very impractical',\n", + " 'Very attractive!'],\n", + " 'text': [\"This spray is really nice. It smells really good, goes on really fine, and does the trick. I will say it feels like you need a lot of it though to get the texture I want. I have a lot of hair, medium thickness. I am comparing to other brands with yucky chemicals so I'm gonna stick with this. Try it!\",\n", + " 'This product does what I need it to do, I just wish it was odorless or had a soft coconut smell. Having my head smell like an orange coffee is offputting. (granted, I did know the smell was described but I was hoping it would be light)',\n", + " 'Smells good, feels great!',\n", + " 'Felt synthetic',\n", + " 'Love it',\n", + " 'The polish was quiet thick and did not apply smoothly. I let dry overnight before adding a second coat since it was so thick.',\n", + " 'Great for many tasks. I purchased these for makeup removal. No makeup on your washcloths. Disposable, so great for travel. Soft. Absorbant.',\n", + " 'These were lightweight and soft but much too small for my liking. I would have preferred two of these together to make one loc. For that reason I will not be repurchasing.',\n", + " 'This is perfect for my between salon visits. I have been using this now twice a week for over a month and I absolutely love it! My skin looks amazing and feels super smooth and silky. This is also super easy to use (just follow instructions). I can see already that I will begin expanding the time between visits which will definitely help me save money in the long run. Highly recommend!',\n", + " 'I get Keratin treatments at the salon at least 3-4 times a year (would do it more often if I could afford it). I am always in the market to use products that can help extend my salon visits. This Keratin shampoo is really nice. It is sulfate free (which is the first thing I look for ) and makes my hair feel silky smooth and soft. I highly recommend for anyone who wants to improve the texture and appearance of your hair. I really like the fragrance, too.',\n", + " \"I was very disappointed when I got this facial scrub. I had assumed it was like other scrubs I use but it wasn't. This is a powder which you need to mix with water to make a paste before you put it on your face. I have a tendency to like to use scrubs in the shower with me, so this extra step doesn't really work for me. As far as the scrubbing factor goes, it's ok. I didn't feel a real smoothing or softening of my skin after use the way I have with others. The biggest plus is the fragrance (i love the smell of oranges). I won't be repurchasing.\",\n", + " 'This is a really nice moisturizing lotion. It goes on lightly and is readily absorbed into my skin. My skin feels amazingly softer and smoother and allows for a nice base for my makeup to be applied over. You only need a small pea sized amount to cover your entire face and neck. Highly recommend for all skin types, ages and for women as well as men.',\n", + " \"I try to get Keratin treatments every 3 months, but honestly it has been getting costly. So, when I saw this I was excited to try it. I found it difficult to use and almost impossible to get to saturate the back of my hair and straight iron it the way they do in the salon. Front and sides were ok, but I couldn't maneuver the back to get it straight. Then I saw the ingredients after the first time and saw it contained formaldehyde and that was the last time I used the actual treatment. I did, however, use the shampoo and conditioner (and I still am). I wish they sold the S&C separate because I really did like it and I am always in the market for a good hair wash which won't strip my hair between treatments. I will resume my regular treatments at my salon.\",\n", + " 'Really nice small brush. Made well, nice wood made with boar bristle, my son absolutely loves this. It brushes his hair well and keeps him looking his best. This compact size makes it nice to keep in the center console of his car or to take on vacation with him. Highly recommend!',\n", + " 'I had never tried anything for my skin consisting of pomegranate, so I was anxious to try this. It actually is an entire skin care regimine containing a cleanser, a toner, a facial cream, an eye cream and overall moisurizers. I actually was quite surprised how well this worked from start to finish. It was nice having an entire skin care routine in one package (instead of me working with various separate products. Fragrance is light and smells almost apple-like (but very light). I particularly like the cleanser and the toner. It also comes in a beautiful gift box so this would make a wonderful gift for someone. I bought another for my mother-in-law and plan to give it to her when we visit next month. Highly recommend!',\n", + " \"When I saw this, I was thrilled to be able to try it. I have suffered from bags and dark circles under my eyes for years now. I have been 'using' this for almost three weeks and I am not happy with it. First, it's almost impossible for me to keep it in place under my eyes. They come wet out of the packet and I was unsure what side was supposed to be placed on my skin. They do not stay in place and I found them falling off easily. Of course, maybe it was me or my skin, so please don't just rely on my review (read others). I will not be reordering.\",\n", + " 'This is a great hair straightener. Heats up quickly and evenly, makes it easy to take the curl out of my naturally wavy hair. It fits easily in my hand and maneuvers around the front and back of my head easily. Does not heat up my countertop (keeps the heat on the iron). I love this pink, too, it matches my decor perfectly. I highly recommend this Bellezza styler.',\n", + " \"I really like these ear swabs. First they come in a large, handy box and are easy to store (will last a long time). Second, they are all organic and good for the environment. Third, they are strong and don't fall apart very easily. I highly recommend these over Q-Tips (which I have used for years).\",\n", + " 'To be honest, I rarely have used an overnight cream. Typically, my skin care routine is the same morning and night (wash, apply hyalauronic serum, and some kind of moistutrizer). So, when I saw this Iryasa cream I wanted to try it. Easy to apply, you can immediately feel the moisture starting to work. I do apply this about 30 minutes before I actually go to sleep to allow it time to be absorbed (before putting my face on my pillow) as it is a thicker type of cream and needs time. My skin in the morning feels better than ever. Soft and supple, I definitely feel a difference after using this for over 2 weeks now. I highly recommend this cream for women and men.',\n", + " \"At first when I saw this, I wasn't sure what this. I looked at the reviews (which were mostly positive) and thought I would give it a try. My skepticism was quickly diminished after trying this for just a few days. I typically shower every morning and I have Vitamin C and Retinol that I apply to my face. So, when I got this I put it in the freezer and followed the instructions. So, instead of just applying the serums to my face, I started using this roller along with the serums. After less than a week I noticed much less puffiness around my eyes (and I am prone to that area to have bags and puffiness). I also noticed my skin looking noticeably better overall. I think applying this roller to my skin allows the pores to absorb the serums faster and deeper. I will continue to use this going forward. I am really impressed with the results!\",\n", + " \"This a really cute kit which would make for a great gift for someone. It is in a little leather like pouch and has everything you need to give yourself a quality manicure. The nail clipper is a perfect size and works just as well on a women or man's nails. The file is nice as well (although I still prefer to use emory boards on mine). I actually bought another one of these to give to my son as a stocking stuffer this last Christmas for him to use at college. Just a nice, quality made kit at a reasonable price.\",\n", + " 'I love this combo package, particularly the flosser. This makes a great gift package for someone you love, giving them everything they need to keep their mouth/gum health optimal. I have had issues (particularly gums) for the past 5 years. No ones fault but my own for not taking care of my mouth the way I should have all these years. This flosser is great. I fill it with Act Restoring mouthwash and use it after brushing. It amazes me how much stuff this flosser removes with a simple puff of air. Of course, you can purchase both these items separately, but you save in getting them together. Sonicare makes the best tooth/gum care products on the market bar none!',\n", + " \"I don't see the fuss with this toothbrush. As was mentioned in other reviews, it is smaller and more lightweight than other rechargeable toothbrushes. But, beyond that, I just don't get i. I stopped using my older Phillips Sonicare to use this for the past two+ weeks. The vibrations on this brush are very small and I find myself pushing the toothbrush into my teeth and scrubbing to be sure they are getting clean. Maybe there is some secret sonic vibration thing going on, but it didn't happen for me. If I didn't actually have to still 'brush my teeth' manually with this electric toothbrush, maybe it would be fine. However, it's not the case. Without manual intervention, my teeth did not feel clean. As an fyi, I stopped using it this morning and went back to my Phillips.\",\n", + " 'So many great diverse colors',\n", + " 'Got my new eyebrows in mail today. Magically my baby caterpillars grew into gorgeous mama size ones. Papa caterpillar loved the look. And the eyebrow pen, tweezers and brow shaper templates were just an extra nice bonus! Thank you.',\n", + " 'i had a small one that just got destroyed these wires are much longer and bigger i expect to live a lot longer than the tiny one i had !',\n", + " 'its OK not as good as the original Wet Brush just a knock off',\n", + " 'nothing special unfortunately i waited too long to return them .... no results at all dont waste your money',\n", + " 'I love the cocoa butter and shea butter. I hear the shea butter up and whip it until it softens.',\n", + " \"I think I need to stick with my 5 blade razor. This razor is not only difficult to hold & is made of a hard slick plastic with no grippers, but doesn't shave as well as my 5 blade razor. The style is nice, but the functionality is not.\",\n", + " 'A total waste of money. I get better results using a tea bag to alleviate under eye swelling.',\n", + " 'Didnโ€™t expect much but got a nice beautiful surprise! These are nothing short of awesome. Stay on your head - no matter how big your noggin is or how much crazy hair you have. I need to buy more - my daughters have taken all!! The price, quantity and quality is nothing short of โ€œ best deal everโ€!!!!',\n", + " \"This halo hair extension is simply put, garbage. Now, you get what you pay for. And this is a very cheap version. The faux hair is very shiny and looks literally like bad barbie hair. It looks WAY better in the photos than in real life. The color is horrific, in my opinion of course. The streaks are like paint strips. And all of that would be one thing - but the worst is that the hair completely fell out! I had hand fulls of hair strands just trying to put the halo on! And you might think - well, maybe a little loss is to be expected? Except this was handfuls and handfuls. I literally dropped the whole thing right into the trash. I would say this one is a pass for hair loss alone. Having said all of this, I never hesitate to update my reviews should new info seem useful. All of my reviews reflect my honest, personal experience with the reviewed item - your experience may be different. I am not influenced by any outside source. I receive/accept NO free products or discounts that are not available to all shoppers- ever. For some reason our shopper ranks are no longer visible - so, to give you a little more info about me, I am a top 50 reviewer (#30 the highest rank achieved). Those numbers used to fluctuate over time - up and down but I noticed that they stopped updating regularly - perhaps to phase them out. It's a shame because it did help you see who has been around the longest and who is a trustworthy reviewer.\\xa0 I've been doing reviews for over 25 years with Amazon - over 6,000 reviews posted, those reviews have been viewed well over 50,000 times, including well over 25,000 likes. Bottom line, I pay for all my stuff, just like you do.\",\n", + " \"I purchased these to see if I could set my mom's hair. She has fine, thin, short hair and I think these could be fun once in a while for a fluffy set. Mom is 81. These are super old school - hoping I can do it with a little foam styling product.\",\n", + " \"I purchased the tool for my 80 year old mom because she like to file her own toes and fingers. This tool makes it so she can. The thing I don't like? That you have to purchase ALL four files - the buffing files (2 of the 4) are useless. So - it would be nice to be able just to purchase the green and blue ones. The buffing files just go into the trash.\",\n", + " \"I'm a BIG wet nap fan. Always have been. They smell good. They are just the right size. I carry them every where. They don't leak like a bottle of hand santizer and fit in any pocket. 1000? Yeah. It's alot...but I'm happy to use them freely. And quit looking for ways to pocket them at a restaurant. :) They arrived quickly (I have prime) and in very good shape!\",\n", + " \"Rrain hats are really handy when
one doesn't have an umbrella, and
easy to carry in a purse or pocket.\",\n", + " 'Worked out fine. Just a bit tight, but o.k.',\n", + " 'Works very well',\n", + " 'Normally I like NYX products but not this one. It leaves a funny coating on your eyebrows and pushes them down so much they look thinner than they are.
Not worth it.',\n", + " 'These fall apart easily...I would not buy again',\n", + " 'These are nice and fit well and the masks loop in the right place to stay on your face',\n", + " 'These are not what I was expecting. They are super nice quality and can almost be used as ear warmers. Vey thick and plush. I ordered 3. One for my grand daughter and on for each of my nieces. They love them.',\n", + " 'Very natural, light weight and good quality. I use on brides who are not use to lashes but still want a bit of length and definition.',\n", + " 'I bought a pack of these and loved themso much I immediately bought another pack. They are perfect all around and the price is great!',\n", + " 'Havenโ€™t worn it very long yet so canโ€™t comment on longevity but looks great and dried pretty fast.',\n", + " 'Plastic does not bend for matching your brows and will not lay against your skin for tinting at all. The shapes included are way too large and do not match the natural brow lines. Total waste of money.',\n", + " 'Adorable and hold up just fine',\n", + " 'Loved it. The words worked out fine but the single pins broke right out of the package, so I threw them out, but I didnโ€™t buy these for the single pins.',\n", + " 'Be careful there are 3 similar looking packets in the box. 2 are peels and 1 is a moisture mask.',\n", + " \"Great multi pack of bands for a great price. They wash well in the laundry and don't lose any elasticity\",\n", + " \"I'm loving this!
I've been looking for a great serum for fine lines and have tried many. However my skin can be very sensitive so with many that I've tried, I've found that I wake up with puffier than usual eyes and some have even caused significant flaky dryness. Not this one! Have used nightly for a few weeks now and absolutely no issues. Absorbs quickly, nor burning.\",\n", + " 'Easy to use',\n", + " 'Use it for my everyday cologne',\n", + " 'Wife gave them to a friend',\n", + " 'Great product',\n", + " 'These diamond are absolutely beautiful and shine so well. Not cheesy like some of the colored diamonds can, does not look like cheap plastic at all.
I would definitely buy again.
Follow me on Instagram @theenailgame',\n", + " 'sizing is all off',\n", + " 'Super cute and great value!',\n", + " \"This is rough on the skin. I don't like it. Not sure what it's supposed to do.\",\n", + " \"This mask support works great. It does what it's supposed to do. It keeps your mask off of your mouth and nose, allowing more airflow. You mouth and nose are still covered, but the fabric isn't right up against your face.\",\n", + " \"my hair is long. It took a long time to get these put in. The curls were great. These rollers would be great for someone who wants to sleep in them. I didn't find it worth it to use during the day.

Good curlers with no heat. I prefer my hot rollers.\",\n", + " \"I do like the angle of this dermaplaning blade, other than that, it's basically a razor. It preforms just like any other razor blade other than the way you hold it. I can't say it's something special due to this. The cleaning brush is great and needs to be used since the hair stays in the blades.\",\n", + " \"4 stars because it pulled my skin off on the sensitive crease on side of my nose. Just be careful if you have a tough spot upon removing. You must rewet it if it is sticking too strongly. I started on that spot and didn't realize it was tearing my skin. If you follow the instructions, you should have no problem.\",\n", + " \"I really love this blush it's super cute ultra kawaii and I personally am a fan of the changing pictures that it comes with so it's awesome I guess I just wished it was eyeshadow instead the sailor moon one is also cute but too expensive in my opinion and the blush is not a big deal but this item is more like collection stuff but it's really worth it if you want a cute gift or just something really cute to stare at :) /play with for a bit.\",\n", + " \"This spray smells amazing, it does claim to be completely natural so I am wondering if it really is since the smell is very well... processed in my opinion, that being said, it does look completely natural it's completely transparent and once you apply it it doesn't feel as sticky as other products I've used before it really gives the hair a very natural look and for having just applied it a few minutes ago my hair feels extremely soft to the touch which gives me a pretty good idea that this is a good hair spray. The presentation is really pretty and looks cute and clean as well. I love it! I just hope it works well in the long run! The only problem I had (completely unrelated to the spray itself) is that they left it at my neighbors door instead.\",\n", + " 'Had originally planned on using this for my feet but given I have some cracks it mentioned not to use on cracked or hurt feet because it could sting and other similar side effects. I am not sure whether to use this product or not because it also mentioned that it is possible that it will sting whether or not you have cracks on your feet or anything similar. I am a little worried if I should use this at all. I am gifting this away because I do not want to hurt my feet. I hope it helps someone else.',\n", + " 'Very surprised! I am please with first round on my black, dyed hair. Turned a dark brown! Second round in a couple of days. (Suggest a leave in hair oil from scalp to roots for before and after use) hair is soft after use. Has an odor, but not overwhelming if you cover with disposable hair cap. Easy to use.',\n", + " \"This lip butter is pretty much a lip gloss. I haven't noticed any lip plumping action, but it is hydrating. It smells wonderful! There's a slight pinkish tinge to it, but it's sheer and not very prominent. It doesn't last very long and does transfer.\",\n", + " \"I am enjoying this face cream. I find it to be luxurious. It's nice and creamy. The glass jar is very nice. It smells wonderful. It doesn't irritate my sensitive skin. I've been using it at nighttime because it is a heavier cream. I haven't noticed any miraculous results, but I am a regular user of anti-aging products, so I like to think that this is just continuing what's already going on.\",\n", + " \"This is a good way to use a face oil. Normally I skip facial oils because I don't like the way they feel on my face. This one is mixed with a cream, so it doesn't leave your face feeling greasy or oily after applying it. It has a pleasant scent. It isn't sticky though it does leave behind a little tackiness, but that disappears quickly. I'm not really sure what it's supposed to do. I like it. It's definitely hydrating. I do think the descriptions are pretty vague. It doesn't bother my sensitive skin, which is always a plus.\",\n", + " \"I'm in my mid-fifties and I have been using creams targeted to the neck and chest area for a few years now. I have definitely seem some improvement in the texture of that skin. This bottle is very small. It's a lotion consistency and it has a light pleasant scent. It doesn't leave my hands feeling sticky, but the bottle is sticky. I have washed it at least once and it remains sticky. It absorbs quickly. I can't tell if it's doing it's job as I haven't seen any noticeable changes, but it isn't hurting anything either.\",\n", + " \"This night cream has a good, thick consistency. It's definitely a cream and not like a balm. It has a strong scent to it. It smells like a flowery perfume. It smells nice, but it is strong. If you are sensitive to smells, this may not be for you. I don't have any problems with it, though I do prefer citrus scents over flowers, but that's just a personal preference. It doesn't leave my skin feeling sticky or greasy. It absorbs pretty well.\",\n", + " \"I really like this face oil by Dose of Colors. It is fragrance free, but it has a light, pleasant smell to it. It does feel a bit oily, but that goes away after several minutes. I'm only using this at nighttime, because it's too heavy for daytime use in my opinion. It doesn't annoy my sensitive skin. It leaves my skin feeling super soft!\",\n", + " \"I enjoy sugar scrubs! They are wonderful for smoothing rough elbows. This one is a small container. I would consider it more of a travel size or sample size. It smells good. It's got a fruity/beachy smell to it. The scrub has a coarse texture which makes it better for exfoliating, yet I didn't have any troubles with it being too rough on my skin. It is very emollient and has a waxy feel to it. Because of the waxiness, it coats the skin. I used some on my feet and they became a bit slippery on the tile shower floor. I have had some scrubs that leave you feeling super greasy and waxy, but this one is more of a moderate level of greasiness. It definitely softens the skin.\",\n", + " \"This perfume by Shakira has a pleasant scent. I can detect sweet and spicy notes in it. It is not very strong, which is good. It definitely fades over the course of the day, but I can still detect light whiffs at the end of the day. The bottle is attractive, but the cap or lid is way too plain. You have the sexy body shaped bottle and then there's a little clear plastic lid that has not aesthetics at all. If you could be the lid to anything and doesn't stand out at all.\",\n", + " \"I am in my early fifties. I have been using anti-aging products for the past several years. This eye cream has minimal smell to it. The consistency is a thin cream. It's not runny, it's just not thick. I have sensitive eyes and this is non-irritating. My eyes water a lot and that often leads to product getting into my eyes and causing stinging and or burning in the eye area. This cream has not bothered me at all. I haven't noticed any difference in the appearance of the skin around my eye, but because I am a regular user of similar products, I really wouldn't expect to see anything new or different. It does seem to hydrate the delicate skin area.\",\n", + " \"I like wearing eye masks such as these. They are refreshing and energizing. I store them in my small beauty refrigerator which makes them even more enjoyable. After wearing them, I felt ready to take on the world! It comes with a little spatula so you can take them out of the jar without touching them. It felt like they were slipping as I wore them, but when I went to the bathroom to remove them, they were still in place where I left them. One thing I like about this type of eye mask is that it's easy to go about your day while wearing them. I didn't have any issues with sensitivity thankfully. My eyes are super sensitive.\",\n", + " \"This is my first scrunchie. I have not had my hair cut in about 9 months because of the pandemic, so my hair has gotten longer than I've worn it in years! I'm in my early 50's and it's a little below my shoulders now. My hair is thick and coarse. It's long enough to wear in a messy bun for the first time in years! The scrunchie is easy to use and holds up my thick hair pretty well. I don't have to readjust it because it's falling. You can feel the coils inside the fabric. I find it fascinating how it works. When I take it off, it shrinks up again. I like it!\",\n", + " \"I recently took the Pinrose fragrance quiz on their website and this was the scent that was recommended for me. It's okay. I don't dislike it. I definitely don't love it. It's a musky floral scent. Floral scented fragrances are not my favorites. I prefer either fruity or sweet. This supposedly has peach notes in it, but I don't detect them. Fragrance is a very personal thing and it can smell differently depending on your body chemistry. I do like the concept of the petals. They're basically scented towelettes. They are fairly dry so you're not dripping in scent. I'm planning on putting some of these in my daughter's Christmas stocking. These are also great for travel!\",\n", + " \"These Pinrose Gilded Fox petals are a fun way to try out a new scent! The box comes with 12 packets. Each packet has a fragrance infused towelette. They aren't too wet, but you are able to rub or wipe them on your pulse points or wherever and transfer the scent to your body. This one has a very interesting smell. At first I didn't detect the chocolate, so it's a bit subtle. The smell is a powdery sweetness with a hint of chocolate. I threw away the wipe in my office trash can and caught pleasant whiffs of it throughout the day. Since the box comes with so many, I plan to put some in my daughter's Christmas stocking so she can try them out. They would also be great for traveling.\",\n", + " \"I have tried several different brands of face wipes. These have to be some of the best ones that I have ever used. They have a wonderful, refreshing scent to them. They are wetter than most wipes I have used which makes them more effective at cleansing the face. The cloths are a good size and pretty soft. They didn't irritate my sensitive skin. The package did rip as I was trying to remove the open sticker, so I have put them inside a plastic baggie so they don't dry out prematurely.\",\n", + " \"I am in my early fifties and my morning skincare routine calls for Vitamin C serum. This doesn't smell like most other Vitamin C serums that I have used. It has a neutral scent that doesn't linger. The serum consistency is thick, but runny. It's a bit oily and doesn't absorb quickly. My skin can be sensitive at times, but I didn't have any problems with this. Overall, I like it, but I don't love it.\",\n", + " \"It's difficult to find some targeted skincare products in travel sizes. I can usually find cleansers and moisturizers, but serums and eye creams are not so easy to track down. This travel set comes with a foaming cleanser, an eye cream, a serum, and a moisturizer as well as a beauty spritz. I wasn't sure what the spritz was for, so I sprayed it on my face after washing it, kind of like a toner, but later I discovered that it's more of a setting spray. The sizes are typical for travel. They're small and should last up to a week, I'm guessing. The individual products seem to be fine. I've used the foaming cleanser before, but the other items were all new to me. The scents were light and floral. None of the products were irritating. I have sensitive eyes and skin and nothing bothered them. I do think the kit is a bit pricey, but that's not affecting my review.\",\n", + " \"This set of gel nail polishes comes in a nice variety of colors. The brushes seem fairly comparable to other nail polishes. What I really like is that there is a little window on the front of each bottle that shows you the color. I've ordered some gel nail polishes that have no color identification on the bottle and I have had to paint (and tape over) a small dot of polish so I can identify them without opening. Overall, I am pleased with these.\",\n", + " \"I work at home, so I can't get by without wearing a face mask for a good part of the day, but I do wear one if I am going out. I have had issues with some masks not staying over my ears. This is a good way to utilize those masks. The headband is comfortable and light weight. It has some stretch to it. The buttons are a little loose, so I tightened them before I wore the headband out in public. I found that I had to pay attention to how I was putting it on my head so the buttons were even, otherwise my mask was crooked. It's definitely a helpful item.\",\n", + " \"For a new (or at least new to me) brand of hand sanitizer, I am pleased with it. I like the pump dispenser which is easy to use. The bottles are a good size. While you can detect the smell of the alcohol, it's not too strong or overpowering like some can be. With so many new brands out there these day, I wouldn't hesitate to purchase again.\",\n", + " \"I am in my early fifties. I found a multi-step skincare routine a few years ago and I follow it pretty regularly. The final step for both the morning and evening is face oil. For the longest time, I skipped that step because I didn't want my face feeling oily. Plus, it just seemed that it would clog pores and lead to acne. I recently tried a different face oil and found it wasn't a bad step at all. This oil has a nice, essential oil smell to it. The only ingredient that I can detect by smell is the lavender. It's not overpowering, but it is noticeable. The oil absorbs quicker when it's applied to dry skin. I tried it out on the back of my hand and it absorbed nearly right away. When used as the final step in my skincare routine, it took much longer to absorb. It leaves my skin feeling really soft! I haven't had any problems since using it. I personally only use it at nighttime because I don't want my skin looking oily, even for a little while, during the day.\",\n", + " \"This is a light weight serum. It has a runny, liquidy consistency that's non-greasy. It doesn't leave behind any stickiness or tackiness. There is no scent to it either. It absorbs really fast and immediately hydrates your skin. It leaves a smooth finish. It's non-irritating and doesn't annoy my sensitive skin.\",\n", + " \"I wear headbands like this in the evening when washing my face and following my skincare routine. These headbands are very soft. I found these to be a little small, but they do stretch enough to accommodate my large head. I have just had other headbands that were a little larger and didn't require being stretched to the max just to fit. I like the variety of colors and have shared these with my eighteen year old daughter. One thing that I do like is that the bow doesn't get off centered as easily as my old one. My old one has to be adjusted every time I put it on. This one seems to be just fine.\",\n", + " \"I guess I'm not the right target audience for this Vitamin C/Retinol Moisturizer. I'm in my early fifties. Both of those ingredients are part of my daily skincare routine, so I thought it would be perfect for me. I did not see the recommended for ages 20-30s before ordering. It has a light, barely noticeable citrus smell to it. It absorbs really quickly but in doing so, I found it to be over drying on my mature skin. Other than that issue, I didn't have any other problems with my sensitive skin. Luckily, I have an eighteen year old daughter so I will pass it along to her to use.\",\n", + " \"This serum is more the consistency of a lotion than serums that I have used in the past. It has a nice fruity smell. It doesn't irritate my sensitive skin. The serum absorbs quickly and isn't tacky or sticky. I am in my early fifties and use an assortment of anti-aging products daily. I haven't seen any new miraculous results with this, but it does moisturize. As a regular user of such products, I really don't think I would see anything new from them, but rather a continuation of what I have already started to achieve.\",\n", + " \"I apply body lotion every morning and night. This one is a thinner lotion than some, but it absorbs quickly. My skin just drinks it up! It's non-greasy and has a light, pleasant scent to it. The bottle is a little oddly shaped. It's thin and flat which makes it a little difficult to grip in my opinion.\",\n", + " \"Last summer I decided to grow out my bangs after having them for all of my adult life. I hadn't used much hairspray since the eighties and into the nineties, but I found that I needed to spray my former bangs in order to help train them to their new position. This is a huge bottle of hair spray. It has a standard hair spray smell. It gives a nice mist. It doesn't leave my hair crunchy. It's a flexible hold so my hair moves and looks natural. So far I am pleased with it.\",\n", + " \"As I have gotten older (I'm in my early fifties), I've noticed that my eyelashes have become sparser. This eyelash growth serum is easy to use. It doesn't sting or irritate my sensitive eyes either. I haven't seen much change in the length of my lashes yet, but I think I can see some new growth or density. I will continue using this and update my review if necessary.\",\n", + " \"This goat milk cleanser is very gentle. I have sensitive skin and it doesn't irritate or annoy my skin at all. It has a pump dispenser that works nicely. It's thick, like a lotion consistency. The cleanser doesn't lather or foam. I haven't been able to notice any scent, good or bad. It doesn't dry out my skin. I'm very pleased with it.\",\n", + " \"'Tis the season for dry hands! I go through a lot of hand creams in the winter months. This lotion is not too thick, but it's not runny either. It absorbs nicely and doesn't leave behind any greasiness. It has a light, fruity scent that's not overpowering. In fact, I found it to be barely noticeable. It is very moisturizing and leaves my hands soft. I would order this again.\",\n", + " \"I've used sonic toothbrushes before. I like the pink color of this. It comes with a travel case and extra brush heads. There are several different speeds/settings that you can use. As far as I can tell, there isn't a timer on it which would be nice. The bristles are pretty firm. I'm guessing maybe they are a medium. It does a good job of leaving my teeth clean.\",\n", + " \"I am in my early 50's and have been a regular user of anti-aging products for the past several years. This serum comes in a glass bottle and has a dropper applicator. It takes about half of the dropper to cover my face. It has a tacky (but not sticky) feel to it which remains for a while even after it has absorbed into the skin. The microbeads have to be crushed or else you have little white beads on your face. It's not difficult to break the beads. I just press on them and they rub into the skin. After applying the serum, my face was really dry. I have been using this at night. I have a multi-step skin care routine so I followed this with my nighttime moisturizer, then retinol, and some face oil. The serum doesn't irritate my sensitive skin. There is a mild scent, but nothing that I could recognize. Overall, it's okay. I haven't noticed any tightening or improvements in my skin. However, as a regular user of anti-aging products, I wasn't expecting anything new.\",\n", + " \"My husband started a business recently and was looking at options for his bookkeeping. He knew that he wanted to use QuickBooks from his previous experience. Originally he was going to use the web based version, but since this comes with a year of enhanced payroll, he decided to go with this. He consulted with an accountant in getting it set up for his company's needs. He did have to contact customer support to help him get the enhanced payroll feature working. For some reason, it had the number 1234567 prefilled and he couldn't change it without customer support. So far it has been easy to use and has done everything he's needed it to do.\",\n", + " 'These hair towel wraps are the softest hair towels that I have ever had. They aren\\'t the typical \"dry\" microfiber material that other hair towels tend to be. My daughter hair goes past her shoulders a bit whereas mine is about chin length. They wraps work well for both of us. They stay in place well and take a lot of the water out of our wet hair. The towel doesn\\'t get too heavy when wearing it either. I love the variety of colors. These really look nice and come in a gift box. They would make a great gift!',\n", + " \"I have been using jade rollers for the past few months. This is my third one. The first one that I bought was much larger than this and I found it to be a bit awkward at times. Plus the end that rolls around the eyes was a static piece, not a roller. Then I tried a smaller one more recently. It was fine, until the eye roller piece broke off. The metal piece that holds it in never felt really sturdy and when it broke, I wasn't really surprised. This one is the nicest one I've tried. It's a great quality and very sturdy. The size is perfect. The directions say to chill it in the refrigerator, but I have found that it's usually cold enough just leaving it out on my bathroom counter. I use it primarily to help my serums and creams absorb into my skin better. This comes with another tool, a Gua Sha, which I was unfamiliar with. They both were in a nice drawstring bag and would be perfect for gift giving.\",\n", + " \"I have one of the original Makeup Erasers and to be honest, I can't tell the difference between these cloths or the original one. Well, that's not entirely true, I can tell the difference. These have a hanging loop and the name brand ones don't! Side by side, they are identical. These are just as soft. They do an impressive job of removing makeup, especially mascara. They are gently on my skin. These come in a set of 2, plus the set is half the price of the original. I will be ordering some of these for the girls in my life!\",\n", + " \"My daughter received a UV Light Manicure Light last year for Christmas from her aunt. It came with a couple of colors, but she is thrilled to have this nice variety of colors now. The quality of the nail polish is comparable to other gel nail polishes that we have bought. It works as it should. She has polished her nails once so far with this set. As of now, it's been one week and they all look as good as the first day. Usually gel polish lasts for about 2 weeks on her, so at this rate, she thinks the results will be the same. One thing she didn't like was that the bottles are not labeled or marked to indicate what colors they are. To solve this, we put a drop of nail polish on the back of each bottle. The polish wouldn't dry without the LED light, which we realized after 5 hours of waiting. So we took a piece of clear tape and covered the polish drop. So now she can easily identify the right bottle without having to open each one.\",\n", + " \"I love coffee scrubs. This one is a new favorite. There are two types of body scrubs. Dry ones that are like sand and don't clump together or ones that have a lot of oil that cause it to clump together. This one is a dry one. It comes with a little scoop which is nice. My last dry coffee scrub that I had did not, so it actually was a bit messy to use. The directions say to scrub it on your skin and leave for a few seconds before rinsing. Most coffee scrubs that I have tried say to leave it on for a few minutes which I find to be nearly impossible unless you turn the water off. The smell is amazing - a rich coffee scent that is perfect for slow moving mornings. It does leave behind an ever so slightly oily texture, but it goes away after toweling off and leaves behind soft skin. I haven't noticed any difference in my cellulite, but I have read that caffeine helps with it. I don't use it for the cellulite. I like to use it for exfoliating my skin.\",\n", + " \"A few months ago I got a vanity mirror that magnifies 5 times. Until then, I didn't know that I had a blackhead problem. I don't always have blackheads, so I don't use this every morning. But when I do notice blackheads, I use this for a few days until they are gone. The product is white and has a very fine grit to it. The grit scrubs away the blackheads. It does not hurt or irritate my skin. It doesn't take a lot for each use so it should last a while.\",\n", + " \"I am in my late 40's and started using anti-aging products a few years ago. Because I have been using products to work on wrinkles and younger looking skin regularly for the past few years, it's difficult to see new results. This eye cream is a nice creamy consistency. I don't notice any smell from it at all. I am able to apply this to the eye area of both of my eyes with just one dispense from the pump. It absorbs nicely into my skin and keeps my delicate eye skin well hydrated. One thing that I especially like is that it doesn't sting my eyes! I have ultra sensitive eyes and if I sweat, make up and skin care products will often get rubbed into my eyes. Some products cause them to sting or burn. We're having a hot summer here in Georgia and even with sweating, I have not had any issues with it stinging or burning. I've had to stop using some of my favorite beauty products in the past for that problem. I'm very happy with this eye cream so far!

*I received this for free in exchange for my honest & unbiased review. My thoughts & opinions are my own.\",\n", + " \"This is the 3rd peel foot mask that I have tried. The others have been unsuccessful. Still wanting to experience the foot peel, I tried again. The first thing that makes this foot peel better than the others is the foot slippers. The slippers are actually a medium thickness plastic. They remind me of the โ€œrubber pantsโ€ that my little boy wore over his training underwear when he was 2 years old. These slippers also fit the best of the three that I have tried. I had problems with using the tape, but because my feet are on the larger end, they stayed in place well without it. I wear a size 10 W shoe and these fit my feet fine. They were not too tight nor did I have to stretch them to get them on. They were a little confusing to figure out. The directions said to โ€œcut on the dotted lineโ€ but I couldnโ€™t see any dotted line. The 2 slippers were attached together at the top. So I cut them apart and then I had to snip a little off the top to open up where my foot was to go inside. This foot peel has a somewhat pleasant scent. I was worried because one of the ingredients is vinegar and another is fermented milk. Those did not sound appealing at all. However, what I smelled was a combination of the ginger and the chamomile. The hardest thing about this whole process was carving out the time to do it. You have to soak your feet for 15-30 minutes before hand. Then you have to wear the foot booties for 70-90 minutes. Then soak for another 15 minutes afterwards. Iโ€™m a busy mom, so itโ€™s hard to find that much free time. I've just started noticing some peeling, so already it's looking more successful than the other ones that I've tried.

*I purchased these at a discounted price in exchange for my honest & unbiased review. My thoughts & opinions are my own.\",\n", + " \"My daughter and I discovered facial sheet masks over the summer and have become fans of them. They are easy and fun to use. This box of Anti-Aging sheet masks comes with 5 masks. Each mask is individually wrapped. When you open up a mask and remove it from the packing, you see that there are 2 layers. One is the sheet mask which is thin and papery like. The other is a plastic type material. The two layers are together, so I put both of them on my face. The other masks that I have used didn't have this plastic layer. I couldn't get it to lay flat on my skin very well, so I peeled the plastic layer off leaving just the paper one. This was what I was more familiar with. That layer was easy to mold to my face. The mask was very cold which felt refreshing. It's very wet - not to the point of dripping off my face, but enough that you want to spread it around more on the mask as it is on your face. It says to leave it on for 15-20 minutes. I opted for the lesser time because my coffee was ready & I didn't want to wait any longer for it! Then you are supposed to rub any left over "goo" (for a lack of a better word) into you skin. I accidently got a little into my eye, but it didn't burn or sting at all, which surprised me. I have very sensitive eyes and was expecting to feel some pain. I regularly use anti-aging products, plus I have only used one of these sheet masks so far, so I don't notice any difference to my skin, but I would definitely add this to my beauty routine.

*I purchased these masks at a reduced price for the purpose of trying out & reviewing. My thoughts & opinions are my own.\",\n", + " \"I burned my back of my hand in a couple of spots this past fall and have been using FLAWless for a short period of time to see if it helps lesson the appearance of those burns. First of all, I would say it's more of a gel than a cream. It's a tan color and is easy to rub into the skin. It doesn't leave behind any stickiness or residue. It also doesn't have much of a scent either. So far I *think* I might be seeing a little fading of my burn scars, but it's not very obvious. However, I am noticing that my freckles and age spots on the back of my hand are looking less noticeable and that's a welcome result. I am anxious to see what happens after continued use.

*I purchased this at a reduced price for the purpose of trying it out & reviewing. My thoughts & opinions are my own.\",\n", + " \"I am very happy with my Marrywindix acrylic organizer! I have limited counter space for my cosmetics and beauty products. Prior to ordering this organizer, I had all of my lipsticks & lip glosses shoved in a small drawer. Because they were over crowded, I had difficulties finding the ones that I wanted when I wanted them. Now I can easily see most of my lip products at a quick glance. The organizer is only 6 inches wide and 4 inches deep, so it doesn't take up a whole lot of counter space. The acrylic is sturdy & solid and is easy to clean. Recently I have been looking at acrylic organizers recently in my local stores and they seem to be over priced! This one is bargain!! My teenage daughter tried to claim this one from me, but since it is such a reasonable price, I will probably just go ahead & order her one, too.

****Update - I ended up ordering another style of the Marrywindix acrylic organizer for my daughter. This one has drawers in addition to storage on top for brushes & bottles. She LOVES it! It is very well made and looks great! Each drawer comes with a liner to keep things nice and neat.

*I received my acrylic organizer from Marrywindix for the purpose of trying out & reviewing. My thoughts & opinions are my own.\",\n", + " \"I am in my late 40's and always looking for new skin care products to help reduce the signs of aging, so when I was given the opportunity to purchase this serum at a discounted price in order to try it out, I was more than happy to do so. It is the first face serum that I have tried that has absolutely no scent or fragrance. It's a very thin consistency, like water. It took a couple of uses to figure out that I can't just pump a little bit on to my finger because it just rolls off. The absorption rate is pretty quick which I like. It's frustrating when you have to wait a few minutes for a serum to absorb into you skin so you can continue your skin care routine. I'm a busy mom & don't have a lot of time to just wait around! I love the list of natural ingredients!!! I've only been using this for a couple of weeks. I'm not seeing any major improvements with my wrinkles and such, but I am noticing an overall improvement in the texture of my skin. I realize that it often takes longer with continued use before some improvements are noticeable. I'm enjoying it & will update my review after continued use.\",\n", + " \"I sleep better when I wear a sleep mask, so I use them regularly. When I was looking for a new one to replace my worn out one, I was given the opportunity to purchase this one at a discounted price so I could try it out. This is a nice, light weight sleeping mask. I've had one mask before that was super thick & padded, but it was actually more difficult to sleep with. Thicker is not always better! One side is satin and the side that is against your eyes is a soft, velour type fabric. The straps are a nice, thick elastic band which is adjustable with Velcro. I've purchased many sleeping masks which have a thin elastic band that is not adjustable at all. Those eventually get stretched out before the rest of the mask is worn out. This mask does a pretty good job of blocking the majority of the light. A little light can get through the area of the mask around the nose. I don't use ear plugs very often, but it's nice to have them handy when I do need them, so I don't have to fumble around my night stand looking for them.\",\n", + " \"First of all, this is a generous amount of rosehip oil! I've been using it daily for about 2 weeks and I've barely put a dent in it. I've been using it on a burn scar that I have on my arm. The pump lid is easy to use & dispenses a nice amount of oil. One pump is enough for my scar. When I first used it, I was a little concerned, because it comes out a golden color, but when you rub it in, the color completely disappears. It does not leave my hands feeling greasy, which is very important to me. I've been keeping it on my nightstand and applying it at bedtime. If it left my hands feeling sticky or greasy, I would have to get up & wash them. There is a very light, natural scent - it kind of reminds me of a mild olive oil. It's only noticeable when I hold my arm right under my nose. My scar is beginning to diminish. It's still there, but it has faded a little bit. I'm excited to see what happens after more use! The skin around my scar is super soft. I may start using this to moisturize this winter.\",\n", + " 'Needs the charging cord included in the package instead of sold separately.',\n", + " \"only 2 problems with this product--expensive and hard to get. Even if it is the best, I'm switching back to the Oster cleaner\",\n", + " 'Works very well',\n", + " 'Love the colors',\n", + " 'The headbands with the bow on top is soft and so cute, I use the headband everyday when I put on a mask. The other spa headbands holds pretty well too especially when your hair gets in your way when you wash your face in the sink.',\n", + " 'Perfect transaction by this seller. The products are awesome and I would definitely order this again. Great price as well..',\n", + " 'The button locations are way off โ€ฆ but the quality of the headbands are great.',\n", + " \"cheap stuff... bumpy surface, paint is chipping off after one use. It's not worth printing a return label, or a drive to ups.\",\n", + " \"I've worn this for 3 days, I'm a little disappointed the black paint had already started to chip off.\",\n", + " \"I'm very happy with my order. Will order item again. I use it for my nail art .\",\n", + " \"My hairdresser recommended my husband get and use one of these for his thinning hair to use to stimulate the scalp when washing his hair. He also uses it with a rose water spray daily and within six months we have noticed a huge change in the thickness of his hair. I use mine too when I shampoo although I already have incredibly thick hair, and I too have noticed a difference. It also gives a nice lift at the roots too for any ladies with flat hair ( that is why my hairdresser uses them on herself).

Great little pack of two. Almost like a his n' hers. Easy to use due to the grip and easy to pull apart and clean. Had ours a while now and still like new. Really great product and super price considering other places on the internet are selling these exact ones at $40 a piece! Pick up a bargain from Amazon.\",\n", + " \"I'm not a big fan on the top but you could always just cover that with a beanie or a hat. But overall it's really nice looking, super soft, correct length and everything. would but again.\",\n", + " \"At last, gluten-free deli bread! There are a few good gluten-free breads made without wheat, but they just don't have the flavor of this deli-style bread with sour dough in the ingredient list. This is the first on the market that I know of and it is delicious.There are 5 large deli size slices in a package. I find that a half slice for an open-face sandwich is just the right amount for me. For those of us in the gluten-free community, a deli-style bread is the bread most missed. This Schar bread is expensive but worth every penny! P.S. To follow up on this earlier review, Schar has reduced the size of the deli-style slices to about 2/3 of the original size, AND increased the price! I will still buy this bread, but with a heavy heart!\",\n", + " 'I have been using Nutra Nail odor-free nail polish remover for well over a year. It is an amazing product, as it has an oil base that is non-drying to the nails. My local Publix is no longer carrying it and I was so thankful to have found it on Amazon. The \"cons\" are that the Amazon display shows two bottles of the product, which is what I expected to receive in my order. E-mail confirmation of my Amazon order is for 4 oz of product, a big disappointment! I hope that Amazon will correct the display so that customers are not expecting two bottles of Nutra Nail Odor-Free Nail Polish Remover!',\n", + " 'This is super holographic. Love it. Also it dries fast. Obsessed with this color.',\n", + " 'This is really really good. Best Iโ€™ve ever used by far.',\n", + " \"I read the description and thought this was something different than it was. I DID get what I ordered, but it is damaged and the package is open, with paint leaking. I think this happened prior to it being packed for my order because the packing seemed fine between shipper and me. Scared will have bacteria so not using. Not what I'd hoped to get regardless but cute halloween makeup kit and I assume there are stencils in there somewhere. I don't want to open it due to obvious paint leaking inside. Don't trust manufacturing\",\n", + " 'I use this everyday, love it!',\n", + " 'Seems good but have been too nervous to test it out. Will update once I do.',\n", + " 'This is a great lip gloss that feels very light on but also has a good amount of pigment to it. The shade I got is nice and neutral. It makes lips soft. It doesnโ€™t last too long but expected with a more natural product.',\n", + " 'Great shampoo and conditioner set. Smells great and leaves hair feeling clean and soft. I like this brand and have used it in the past. Seems to be great quality.',\n", + " \"This is much faster and less messy than using the cream. Quick any easy. Not the longest hold but good for a few hours. Not much of any smell to it which is probably better. Some of these wax's are way too fragrant.\",\n", + " 'Great soap with mild natural scent. Works great on my sensitive skin. Leaves it soft and clean and doesnโ€™t dry it out.',\n", + " 'Great quality soap! So many good ingredients that are good for skin and hydrating not drying. Smells great and skin feels clean and soft after. Highly recommend.',\n", + " 'These are so popular and I was excited to try but I donโ€™t feel like it did it for me. It was hard to get down to my scalp and move around. Felt much easier to just use my fingers. Maybe I need to practice more of try a different massager. They seem well made though and look just like the picture.',\n", + " 'Great hair wraps that help dry hair faster than a regular towel. I like the different colors and they seem to be great quality.',\n", + " 'Tiny waver that works great to make smaller sized waves. Heats quickly and makes waves quickly. Only took a few minutes to do all of my daughters hair. I only do a top layer of hair and around the face. Find that it looks less poofy this way. Seems well made and good quality.',\n", + " 'Our girls love to play with this wig. Easy to put on and comes with a wig cap. Looks real.',\n", + " 'These look like nice tweezers, similar in look to tweezerman tweezers but for some reason they donโ€™t grip hairs very well and are very annoying for me. They seem to match up perfectly at the end so not sure why they donโ€™t grab well. Will use as backups or keep in purse or car.',\n", + " 'Great set of oils that are great to use as is or when making other products. I used the coconut oil in a roller ball with some tea tree and clove oil for a rash and it works great. They are both have no scent.',\n", + " 'Great set of hair items. Would make a nice gift. Works as described. The material is extremely plush and soft and feels luxurious to wear.',\n", + " 'Decent shampoo. I used it alone without conditioner so I could see how it worked and it seemed to clean my hair well and leave it manageable. The scent is ok as well. While I didnโ€™t notice anything negative there wasnโ€™t anything that stood out to me to buy it again.',\n", + " 'I have been wanting to try these food peels. I was nervous to try but after reading some of the other reviews I finally did and am glad I did. Followed directions and my feet started to peel the next day. No bad reactions or problems. I didnโ€™t use the included tool. Soaking your feet each day helps with the peeling process.',\n", + " 'Great set of nail polishes. My daughter and granddaughter both liked them and thought they were great quality. Nice colors, go on smooth and dry quick. Donโ€™t chip easily and Last as long as other quality polishes.',\n", + " 'Interesting sunscreen. Has a clear gel consistency, goes and smooth and easily. Rubs in great and dries quickly, smells first of running alcohol and then berry. Seems to be effective in preventing sunburns.',\n", + " 'This is a nice cordless, travel size waterpik. It has good power for not being a regular waterpik. Some other cordless ones Iโ€™ve tried havenโ€™t had the same power. This comes with a variety of tips. Is easy to fill and use. Has different settings and power levels. Charges via a usb cable.',\n", + " 'Works well. Pain free. Easy to use. Requires 1 AA battery which is not included.',\n", + " \"From my daughter: I like that you can use this product in a variety of ways, when hair is wet as a leave in conditioner, when hair is dry to protect it from heat styling or after it is styled to add shine. I put some on my hair after I straightened it and it seemed to work well to tame frizz and add shine. It has a light scent that isn't overpowering.\",\n", + " \"This flat iron works well to straighten hair, but I couldn't get it to curl very well like other straighteners I have. It is easy to use and the red light on the dial turns green when it is ready which is nice.\",\n", + " 'Clippers work well. I prefer to use them without the plastic catcher that is attached, but it easily comes off. Nice travel case that includes a nail file. Clippers are very sharp and cut efficiently and smoothly.',\n", + " \"From my daughter: I usually buy Dove, Pantene or Tresemme shampoo. I haven't tried this particular tresemme before, but I really like it. It works great like the other varieties I have tried. This particular one smells like coconut, but not overly artificial or perfume-y. The shampoo works great, leaves hair clean, but not dried out and the conditioner works perfectly leaving hair soft and manageable but not greasy and weighed down.\",\n", + " 'Not greasy or filmy!
Love the look and feel of this lightweight moisturizer! Donโ€™t use too much!
Skin feels amazing every morning when I wake up!',\n", + " 'I have been using this mascara for about 2 months now and I am in awe at the difference in my lashes. And Iโ€™ve used it all! Iโ€™ve tried so many types of mascara even went thru falsies, extensions. And I love this product. It lengthens, plumps, and makes my lashes LOOK healthier. I highly recommend!',\n", + " 'These along with their other scents (I love the blue ones too) are a must. Iโ€™m a face mask and product collector, I have so many masks but these are my top sheet masks for sure!!',\n", + " 'Best stuff ever. My skin was so soft afterwards',\n", + " \"I'm having a hard time but maybe it's me๐Ÿ˜\",\n", + " 'Great for the price',\n", + " 'Great price and product!',\n", + " 'Easy to use, long lasting. Love them.',\n", + " 'Good Product',\n", + " 'Excellent Product. Pleasing Bouquet That Lingers Well. Softens My Skin. Love This Product & Brand.',\n", + " \"Doesn't burn the eyes\",\n", + " \"OK at best. The teeth bend and break in my pocket. That never happened with previous Ace combs. They're making them cheaper.\",\n", + " \"I purchased this for my shoulder length hair. It's very difficult to use, would be best used on longer hair. It's a bit hard to wind the hair around this iron when it's my length.\",\n", + " 'Not what I expected in a scrub.',\n", + " 'Great quality',\n", + " 'Not as shiny as I was hoping but overalls I still love it!',\n", + " 'Cute little earings',\n", + " 'Love the colors and the fact itโ€™s many of them!',\n", + " 'Donโ€™t get it! My hair is falling out! PLEASE google and research these products! My hair has been falling out from the roots for 4 weeks now! Iโ€™ve lost about a third of my hair so far and itโ€™s still falling out!!!',\n", + " 'Gift to a young Family member. They real like the item.',\n", + " 'Iโ€™m using this XXI vitamin C cream with the firming cream.
My face feels smoother, and not breaking out using both of them.
This cream is not real thick, and absorbs well.
I use a little light make up and it goes on smooth over this, then use blush.

I like this, but not noticing a major difference.
Iโ€™m a older women.',\n", + " 'The TRESemmeโ€™ Shampoo and Conditioner has a very nice scent to it.
Before using the shampoo shake the bottle..The shampoo is more like a gel, but did lather up.
The Conditioner left my hair shinny, and smooth..',\n", + " 'Not good for getting out tangles',\n", + " \"It is a nice grip for my clippers but the bottom slides around so what's the big idea!\",\n", + " 'I bought one and after trying it, I bought three more so I would always have one handy.',\n", + " 'Very well made,good quality and very good color.',\n", + " 'Like other nail polish removers, this MOUNTAIN FALLS REGULAR NAIL POLISH REMOVER (for Natural Nails with Vitamin E and Panthenol, 16 Fluid Ounce) is mostly acetone. It smells like all the other nail polish removers that Iโ€™ve tried, and works like them, too.

I use nail polish remover to take gummy stuff off my hands and other things. If you use it this way, itโ€™s important to remember that it can damage synthetic fabrics, wood finishes, and plastic. Also, when using or storing it, remember that itโ€™s highly flammable, and should NOT be used or stored near fire, flames, or heat. (See my photo of the bottle label, with all the warnings.)

The big 16-oz. bottle is equivalent to two of the regular-size bottles (e.g., [[ASIN:B004X8IFEI Sally Hansen Nail Polish Remover]]) that you find at local grocery and drug stores.',\n", + " 'This PHILIPS SONICARE ESSENCE+ TOOTHBRUSH & AIRFLOSS ELECTRIC FLOSSER (Value Bundle) is the real deal. The sonic toothbrush gets your teeth cleaner than a manual toothbrush, because of the vibrating brush head and the 2-minute timer that tells you when youโ€™ve brushed long enough. A nice feature is that the color on the brush head bristles fades to let you know that the brush head is worn out and needs replacing.

The electric flosser works really well--maybe not quite as well as string floss, but itโ€™s definitely better than poking into gaps between teeth with a toothpick on a handle. The flosser is good for cleaning under my bridge, which needs to be kept really clean to prevent gum irritation and swelling.',\n", + " \"These are GREAT! Individually packaged in the box. Don't absorb product. Easy product application. Love them!\",\n", + " 'Have yet to notice any change have been using this product for awhile now',\n", + " 'I received this gift set for Christmas. My husband ordered it from Amazon. The lip balm gets 5 stars! Itโ€™s my favorite. The lotion is such a strong offensive scent that I cannot wear it. I havenโ€™t tried the little bottle yet since the lotion is so heavily scented.',\n", + " \"Whats all the hype about? Its no different than any other exfoliator i've tried. The reviews sold me the product... Nice job
It's worth it, I though, experienced no Magic\",\n", + " 'Gift for vulnerable family members.
Gift was well received and appreciated.
Hopefully these will be used to minimize my loved ones risk of catching COVID19',\n", + " \"Work and fit like the originals at MUCH less cost. I'm sold!\",\n", + " 'I bought this for a great nice for a gift and she loved it. Smell fantastic as well as moisturizing? Great price!',\n", + " 'The product was okay a little to thick to try and wear made my eyes feel uncomfortable a bit to heavy for my liking, l like them thick yet light and easy to apply these were a little difficult staying glued',\n", + " 'I promised to retract the negative review once I received the product. Thank you',\n", + " \"I wish I loved this. This is a nicely packaged perfume in an attractive bottle with a gold-colored tassel hanging from the side. The scent is neither offensive nor enticing. I can't even describe what it smells like. It is so very subtle but it lasts a few hours.

The current price of $44.99 ($49.99 minus $5) is competitively priced for perfume like this but it is not one I would order again as I have to really love it to pay that much.\",\n", + " 'There are six silk scrunchies in this package in different basic colors. They are thin and slinky and are typical of what I expect of silk holders.

These hold my hair well but as is expected of silk, can easily slide out. These are best on long hair because the potential to slide off is not as great. I personally prefer velvet scrunchies to these silk ones because they are \"beefier\" looking. However, for those who want the elegance of silk, then this delivers.

The current price of $20.79 ($25.99 minus 20%) comes to $3.47 per band which is competitively priced for 100% Mulberry silk items like these.',\n", + " 'The photo on Amazon must be wrong. This cream is blue and not white. I hate colored creams. However, this goes on clear and was so super hydrating to my face, that I did not mark it down for the color. Note that the box it came in was all smashed and it was almost double the size of the jar. They could have fit almost two jars of this in the box. In addition, the cream in the jar looks half full.

I love the results but not the packaging or the color or the jar being half full.

The current price of $15.99 for 1.69 fluid ounces is competitive. NOTE THE SIZING (.05 fluid ounces) SPECIFIED ON AMAZON is wrong too.',\n", + " \"The flip top cap has a tab on it that has to be pulled before dispensing this. The cream is very thick and reminds me of Elmer's glue. It is scentless and takes about 30 seconds to absorb. After that the skin is fully hydrated and protected. For the current price of $11.99, this is decent diaper rash cream.\",\n", + " 'I love the tines on this long and short detangling comb.The only thing I do not like is the thin handle. I would have preferred a thick silicone handle so that I could get a better grip.\\xa0The tines are strong and the spacing allows it to work very well BUT there are issues.\\xa0

I have three long-haired\\xa0cats and unfortunately, my cats do no like\\xa0this as it really pulls at their hair. Therefore, I have mixed feelings about this comb. On one hand, it detangles and gets out a lot of hair but on the other, my cats want to bite me when using it. I love how it works but not their response.',\n", + " 'This comes in a one gallon jug. There are two negatives to me. First, the biggest negative is that it takes work to dispense the lotion. Second, this lightweight lotion goes on tacky and takes a few minutes to absorb. Once absorbed, however, it is lightly moisturizing and it leaves my skin soft.

This is vegan per the bottle and the lotion is scentless. My favorite lotion is [[ASIN:B09HYPWMKG Ginger Lily Farms Pure Morocco Argan Oil Butter Lotion]]. That is perfect for a massage as well. It has a fragrance and is cruelty-free but not vegan.

This is decent but the initial tackiness I dislike. The current price of $54.99 for 128 ounces comes to $.43 per ounce, which is almost double the price of the lotion I love.',\n", + " 'I used this on my three long-haired cats and it picked up some hair. Since the surface area of the brush is small, there is not much hair that is picked up compared to other brushes. Also, I tried several of these types of brushes and this one is not as easy to clean as the others. The way this is supposed to work is to retract the bristles with the button and the hair that remains on top can be slid off. Since the tines do not retract fully on the top part of the brush, the hair does not slide off easily. Instead, I have to pick it off.

Note that this is for long-haired pets only; I would not use this with a pet with short hair. I have three long-haired cats and even though this works some, I am not impressed for the two reasons I mentioned above. My favorite brush like this is [[ASIN:B09RH8FMMS this one]].

The current price of $20.99 is outrageous for this as it is about $10 to $12 more than others of better or similar quality.',\n", + " 'This is a nice set of five individually wrapped pink-colored blending sponges all with an angled side. I love the sponges as they are of medium-density.

The flat / angled side is great for smooth applications. They feel good in my hands, blend well, and feel soft against my skin. Since these are of medium density, they do not soak up as much foundation as others that are more airy. I also love that the sponges do not smell. I tried other colored sponges and they smell like pencil shavings or other chemicals and these do not.

These blenders make a great gift for the make-up obsessed. These would have been perfect as gifts for the Easter Basket or as a stocking stuffer because each comes in their own package EXCEPT for the negative issue I mention below.

There is one big negative, however. Each package is marked with a price of $1.55 each. Unfortunately, at the current price of $9.95, it comes to $1.99 per sponge which is $.44 cents more than the price marked. Therefore, I cannot recommend these if they are being used for resale or as stocking stuffers or Easter basket gifts because the price is actually more than it says on the package.',\n", + " 'This is a nice set. It contains a beautiful compact mirror with regular and close-up mirrors on the inside. Both mirrors are small but functional. It is fashioned like a pocket watch. The clasp is solid and the finish is high-gloss like the interior mirror itself.

The saying (see below) on the outside of both sides of the mirror is inspirational. It says \"Beautiful girl you can do amazing things.\"

There is also a small dish for jewelry and a very cheap make-up case all with the same inspirational verse.

In summary, this is a nice gift set. The current price of $20.89 ($21.99 minus 5%) is competitive.',\n", + " \"These bandages have many uses. There are 16 black rolls that are individually wrapped and each roll is 5 yards apiece and 2 inches tall. These self-adhere as the bandage is wrapped around a hand, leg, arm, etc. These stick well. The stretch allows this to be used like kinesiology tape with the exception that one cannot shower with this successfully and each wrap is for one-time use.

The entire roll does not have to be used at once as it depends on the amount needed. When used where joints open and close, such as a knee or elbow, the wrap may bunch up in the crease as expected. However, this is perfect to use as a lightweight version of a carpal tunnel brace by wrapping it around a bad wrist, hand, and thumb. It does not stick to my skin nor to a pet's fur, which is wonderful.

This is versatile enough to wrap around the handle of a tennis racquet to get a good grip or an umbrella or cane handle. There are just so many useful possibilities besides medical reasons.

In summary, because the wraps are two inches wide and are not designed to stick to the skin, it does have a tendency to bunch up if wrapped around a knee or elbow, so it is not perfect for everything. I feel these are great bandages to have in one's medicine cabinet. At the current price of $15.19 ($15.99 minus 5%) it comes to $.95 cents per roll which is on the high side of competitively priced. These are self-adhesive bandages rebranded as tattoo grip tape.\",\n", + " 'This is a nice set of 10 colored blending sponges all with an angled side. I love the sponges as they are dense.

The flat / angled side is great for smooth applications. They feel good in my hands, blend well, and feel soft against my skin. Since these are dense, they do not soak up as much foundation as others that are more airy.

These blenders make a great gift for the make-up obsessed. These are also perfect as gifts for the Easter Basket or as a stocking stuffer. I love that the sponges do not smell. I tried other colored sponges and they smell like pencil shavings or other chemicals and these do not.

At the current price of $8.49 ($9.99 minus 15%) these are a reasonable $.85 per sponge.',\n", + " 'This is a lovely blender sponge. I love that this is dense because it does not absorb liquid foundation as some other less dense sponges I tried previously

What attracted me to this the most are the angles.The two flat sides are great for smooth applications. The tip is great for more precision, such as around the eye. The round ends are good for blending or any large make-up application.

This feels good to hold, blends well, and feels soft against my skin. Also, the sponge does not smell.

In summary, this blender makes a great gift for the make-up obsessed. The only reason I rated this 4 stars instead of 5 is because of the price. The current price of $7.50 is on the pricey side. I tried other blenders of this quality that sell for less than half this price when purchased in a pack of three or more. For instance this [[ASIN:B08QCJ3DF7 set]] currently sells for $2.50 per sponge as there are 4 sponges for $9.99. Even though all the angles are not in one sponge, the functionality is still there and they are dense, which I like.',\n", + " \"[[VIDEOID:f77804a8088c40dfbef6fdcfacf8b15a]] There are three individually wrapped bath bombs in this set along with one bar of hand soap and a package of dried rose petals. In total there are five items. The bath bombs spell MOM with the heart substituting for the letter O.

The outside packaging looks giftable but the inside is just an ordinary uninspiring throw-away box. The fragrance of the bombs and soap is hardly noticeable. It has a whisper of rose aroma and I detect no lavender at all. I did try the letter M bomb in a hand bath and it dissolved in 5 minutes in lukewarm water and a nice foam of suds lasted about 10 minutes. The results initially felt moisturizing because my hands felt a little oily after the hand bath; however, eventually I needed to moisturize my hands with lotion.

With regard to the dried petals, one has to like something like that in their bath because it requires straining the water so that they don't go down the drain. For me, I would never use petals in a bath, so keep the recipient in mind when ordering this.

The bar of soap is the only item that would be used by most people.

One thing I love is that the color of the dissolved bomb did not adhere to my skin, my hand bath, or my towel. That is not always the case with bath bombs today.

The current price of $9.74 ($12.99 minus 25%) comes to $1.95 per item which is reasonable.\",\n", + " 'This is a work of art. It is absolutely gorgeous. It is also a bit heavy and it is fragile. The white flowers appear like they are made of clay. The design is lovely. However, I have short to medium-length fine curly hair and no matter what I do I cannot get this to stay. It immediately wants to fall out. I feel this is best applied by someone who is a stylist and perhaps can affix this with some pins. It is also probably best for someone who has thick long hair than someone with fine hair like me.

I love this but am disappointed\\xa0it does not work for me. Also, this can be used for any elegant occasion and not just by a bride.\\xa0

The current price of $19.99 is competitively priced for this. Note that I ordered the style called \"Silver 1.\" However, what is pictured is a lot longer than what I received. Mine is more tightly compacted and half the size and there were no wires I could stretch out. I actually prefer the shorter version but the product shown really should be the one sent even though this is handmade. Therefore, my recommendation is to return the comb if you are not satisfied and if it is not close to the one pictured.',\n", + " 'This is a lovely set of two sponges but they are not heart shaped. What is heart shaped is the plastic holding the two sponges together with the flat side joining into what almost looks like a heart. Nevertheless, I still love them. The set comes with a great metal sponge holder. The sponges are dense. As a result, make-up does not soak in as easily.

Both blenders have a flat side which is great for smooth applications. These feel good in the hands, blend reasonably well, and feel soft against my skin. These blenders make a great gift for the make-up obsessed. I love that the sponges do not smell. I tried other colored sponges and they smell like pencil shavings or other chemicals and these do not.

The sponges themselves are similar in style to all of the others that I tried before this with the exception that the sponges are on the dense side instead of airy. To me what set of sponges to buy all comes down to the price and the angles one wants on the sponges as well as whether it is for gifting or not. The colors are important too - at least to me. These colors also make it perfect for the Easter Basket.

At the current price of $7.99 this comes to a pricey $2.66 per piece if I count the holder. Most other blenders sell for between $1.25 and $1.75 per piece in a set like this but without the heart-shaped packaging.',\n", + " 'This is a lovely set of three sponges in Easter colors of green, pink, and lilac. It also comes with a great metal sponge holder. The sponges are dense unlike most sponges like this on the market. As a result, make-up does not soak in as easily.

The one lilac sponge with a flat side is great for smooth applications. The typical egg-shaped (pink) and the hour-glass (green) sponges are good for blending or any large make-up application. The hour-glass one is easy to hold in the center.

These feel good in the hands, blend reasonably well, and feel soft against my skin. These blenders make a great gift for the make-up obsessed. I love that the sponges do not smell. I tried other colored sponges and they smell like pencil shavings or other chemicals and these do not.

The sponges themselves are similar in style to all of the others that I tried before this with the exception that the sponges are on the dense side instead of airy. To me what set of sponges to buy all comes down to the price and the angles one wants on the sponges as well as whether it is for gifting or not. The colors are important too - at least to me. These colors also make it perfect for the Easter Basket.

At the current price of $6.99 it is a reasonable $1.75 per piece if I count the holder.',\n", + " 'I thought I would love this headband. It is gorgeous and feels great but the material it is made of is so slippery that it keeps sliding off my hair. It is only for this reason I rated this 2 stars as it is not for me.',\n", + " 'There is one recessed foundation brush in this set along with three blender sponges.

The brush is not high quality. I love the unique container as the brush comes out of the tube the same way lipstick does. However, the container is thin and the bristles are only marginally soft and definitely feel synthetic and are shiny. However, there is no shedding. A brush like this is good for travel where it will be used sparingly.

The star of this set are the three blender sponges. There are two sponges with a flat side which is great for smooth applications. The other sponge is a typical egg-shaped sponge that is good for blending or any large make-up application. These blenders feel good in the hands, blend well, and feel soft against my skin. They do have a slight smell to them but it is not offensive.

The current price of $10.99 for 4 pieces comes to a pricey $2.75 per item. I love the sponges and to me they are five stars; however the brush is 2 stars to me. This brush only makes sense for travel or someone who wants a brush that remains covered and will not soil their other make-up applicators or bag. Note that the packaging is more than double the size of the products within. I can fit three sets of these in the box it came in.',\n", + " 'This is a nice room freshener. The fragrance is subtle but lovely and floral. Some fragrances give me a headache if they are\\xa0too strong but this one does not. I love spraying this in my bedroom. It is also a great fragrance to relax with before falling asleep--no dangerous scented candle needed. It does not help promote sleep for me but it is soothing to my senses. The aroma does not last long--about 15 minutes. I happen to like fragrance, so I do like this linen spray.',\n", + " 'There are 9\\xa0 soft non-shedding make-up brushes in this set. This is a gorgeous set that contains a brush for most uses. There is no fan, eyebrow, or lip brush, however.

Each brush comes individually packaged. In fact it is over packaged. The bristles are velvety soft and they do not fall out, which is great. Their soft bristles feel good against my skin and work like many other brushes I tried previously. I particularly LOVE the large blush/foundation brush. I do wish the handles were a tad longer. Nevertheless, the current price of $8.99 is an super\\xa0reasonable for this set as it comes to $1 per brush.

This is a perfect set for the young teenager starting out on her make-up journey.',\n", + " \"There are 14 brushes in this set. There are brushes for foundation, blush, eyeshadow, eye blending (fan brush), etc. In fact, there are more brushes than I needed.\\xa0

The one unique brush in this set (see photo) is the one that looks like a paint brush. This is perfect for cheek highlighting.

The bristles are relatively soft but not as soft as I expected. They feel pretty good against my skin but not great. Also, the heads have a slight odor. The PU brush case has a tremendous chemical odor and needs to be aired out a while.

This is a bargain basement travel set for someone who is starting their make-up journey. The current price of $11.19 comes to $.80 cents per brush. In this case one gets what they pay for; it's a marginal price for a marginal quality set that is functional.\\xa0\",\n", + " 'There are three packages of wafer thin sheets of soap in 80 sheets each pack. The wafers are attached in the center but pull apart easily. There is also a sliding top tin supplied that will hole 80 sheets. Be careful not to get them wet as even a drop of water causes them to dissolve. When I washed my hands with one sheet, it created a nice lather and left my hands clean. I do not feel that it was moisturizing as claimed. Also, even though there are three wonderful fragrances (lavender & aloe, bergamot & ylang ylang, and jasmine & patchouli) that smell great as a whole 80 sheets, that fragrance does not come through on the hands because the soap is too thin to leave any fragrance behind.

The current price of $13.95 comes to $.06 cents per sheet. I consider these perfect for when using a public restroom that has water but no soap. It is also great for camping or any place where portability is paramount without carrying a full wet bar of soap in a container.',\n", + " 'There are 12 \\xa0supremely soft non-shedding make-up brushes in this set with a silicone brush head cleanerbrush that doubles as a mini-brush holder. This is a gorgeous set that contains a brush for most uses. There is no fan, eyebrow, or lip brush, however.

This is an attractive brush set in matte black. Unfortunately, the color of the silicone cleaner cannot be chosen. I thought I was going to get purple to match with my purple bathroom and I received a pink one. \\xa0

The bristles are velvety soft and they do not fall out, which is great. Their soft bristles feel fantastic against my skin and work like many other brushes I tried previously. I particularly LOVE the large blush/foundation brush. The only thing to note is that because the bristles are super soft, these brushes are more suited for powder applications than cream or liquid.

The current price of $19.99 is reasonable for this quality set as it comes to $1.67 per brush or $1.54 per item if counting the silicone cleaner.',\n", + " 'There are four typical no-frills extra large shower caps (red, tan,\\xa0purple, and black). They fit me but have lots of room to spare. They are waterproof as the water just runs right off the exterior. There is an elasticized strap in the cap that can be adjusted. I adjusted one of them and it looked very lopsided on my head as a result of the adjustment.

Unfortunately, these are not my favorite caps. They are too big and the adjustment throws the elastic out of whack. The current price of $11.99 comes to $4 per cap.',\n", + " 'This clip is gorgeous. If one looks at it quickly, it can easily be mistaken for a tarantula due to the black claws and sort of fuzzy looking applique.

I have short to medium fine curly hair and my hair is long enough in the back to use this clip. It holds on to my hair well and looks great. The only negative is that a couple of the beads are loose on the applique. This not only makes noise (i.e. rattles) but creates a situation where they can accidentally be pulled off if the \"plastic\" thread holding it loosely hooks onto something.

The current price of $11.99 is pricey for this but typical for a $1.50 clip that is all dressed up.',\n", + " 'There are four individually packaged 2.53 fluid ounce tubes of moisturizer in this set. They are all the same tubes. This moisturizer is lightweight and is mildly hydrating. It absorbs quickly and is a good product to use in the summer. I also like the fresh cucumber-like aroma. I did, however, expect this to be more hydrating than it is. It is a decent cream but not excellent.

The current price of $15.00 comes to a reasonably priced $3.75 per tube.',\n", + " 'The colors and design of these 12 headbands are super attractive. They are all double banded and most have a \"knot\" in the middle that can be worn in the center of the head or at the base of the neck. I personally do not like knots in my headbands but these are versatile enough to position the knot away from the forehead without losing the good look of the band.

The colors are great and there is a design for almost every outfit.

Also, the current price of $18.99 comes to a reasonable $1.58 per band. These are definitely pretty and functional and they fit well. There was only one where the material was a hair looser on one side than the other for the top part of the double band. All the others were sewn perfectly.',\n", + " 'These headbands are made of PU leather with what appears to be a cloth covered plastic base. The headbands look good on and are best on those with a full head of hair since they are so large. The glue of the leather to the material was coming apart on one of mine, so the quality is so, so.

However, it also came with two polyester-type cloth headbands, a bow hair tie, and a strip of cloth with avocados on them. None of the cloth bands fit me as they are kid-sized. Also, the material feels scratchy and horrible. The avocado tie is okay and so is the hair tie bow.

The curent price of $12.99 ($18.99 minus $6) is too much for this ensemble.',\n", + " 'This bar of facial soap smells wonderful, lathers well, and feels great using EXCEPT the suds sting my eyes. Also, the bar size is like those hotel travel bars. At the current price of $8, that is absolutely insane. I would not expect to purchase this for more than $2 a bar and that is even expensive for this tiny size. In addition to the price, the fact that it stings if one\\xa0accidentally\\xa0gets suds in their eye is also a negative.',\n", + " \"I love the results of this lotion. It is creamy and not too thin or thick and absorbs easily. I applied this to my face and neck and felt lightly hydrated. It does say there is a UVA/UVB sun filter in this but it does not say what SPF it is. The only other negative is that it took me about one minute to get the product to dispense from the pump bottle on initial use only. Also note the box is four times the width of the product.\\xa0

The current price of $38.40 is pricey for this but it's from France and expected.\",\n", + " 'I have really been getting into silicone spatulas/brush sets for applying face creams, bacitracin on a scar, etc. There are two large wands in this package. They are single-sided and have a flat spatula end for applying creams or gels. The opposite side has a ribbed end that is good for washing my face with soap and water or also for applying mask products. However, if the large soft nubs are used, there is more cleaning involved to wash off the mask product.\\xa0

The only reason I rated this 4 stars is because the wand bends too easily. I would have preferred if the arm was a bit stiffer to make it easier to work with and allow me to apply more pressure.

Overall, this set is excellent and about 7 inches long. It is soft on my skin, pliable, and long enough to hold on to.\\xa0

The current price of $9.90 comes to a competitively priced $4.95 per wand.',\n", + " 'At the current price of $48, this is insanely expensive. Yes the brush is a beautiful blue, with a fantastic gloss, and looks great, feels nice in my hands, and brushes my fine short to medium curly hair well. However, the brush stinks to high heaven and reminds me of the smell of burning rubber tires. Unfortunately, I cannot use this in this condition because I am extremely sensitive to offensive odors.',\n", + " 'This is a lovely set of three sponges in nice colors of\\xa0 pink, burgundy, and teal. It also comes with a great metal sponge holder,\\xa0a silicone brush cleaner, and some cleaning solution. The sponges are light\\xa0and airy like most sponges like this on the market.\\xa0

The burgundy sponge with the flat side is great for smooth applications. The typical egg-shaped (teal) and the hour-glass (pink) sponges are good for blending or any large make-up application. The hour-glass one is easy to hold in the center.

These feel good in the hands, blend reasonably well, and feel soft against my skin. These blenders make a great gift for the make-up obsessed. I love that the sponges do not smell. I tried other colored sponges and they smell like pencil shavings or other chemicals and these do not.

I personally do not use a silicone sponge cleaner. I prefer to use my hands and soap and water but having the silicone cleaner with cleaning solution provided is a nice touch.

The sponges themselves are similar in style to all of the others that I tried before this. To me what set of sponges to buy all comes down to the price and the angles one wants on the sponges as well as whether it is for gifting or not. The colors are important too--at least to me.\\xa0

The current price of $7.99 is a great deal for this.',\n", + " 'There is a lot of lotion (3.38 fluid ounces) for the $24 price tag. This lotion is creamy and very hydrating. It also absorbs quickly. Unfortunately, I am not at all crazy about the eucalyptus scent. If I loved the scent, this would have received 5 stars from me.

BTW, this is good for a man or a woman despite what the title says.',\n", + " 'There are six blush-colored scrunchies and one white scrunchie. The material is a bit slick so there is a chance these will slip out of the hair. I have medium length hair in the back and they did slip out easily if I pulled on them. I do feel these are elegant and super attractive. If the bride and bridesmaids all have long hair, then these are a good option. I have no idea what these will be priced at but anything more than $10.50 (which would be 1.50 each) is too much.',\n", + " 'There are supposed to be six green and one white scrunchies but I received an additional white one to bring my total up to eight scrunchies. However, only seven are supposed to be shipped.

These hair ties are dressy and nice. The scrunchie expands to hold a good amount of hair. Of course, when applying one of these, it is important to turn it so the tail goes down. That can sometimes be tricky.

The only negative I see is that the seam shows the stitching as can be seen in my photo. They should have covered this with the area that is tied (meaning the area where the tail flows down). This is the only reason I took off one star.

The current price of $12.99 comes to $1.86 per scrunchie if one receives seven (and not eight) scrunchies.',\n", + " 'This comb is just beautiful and the quality is exceptional. It is also hefty. As a statement piece it gets 5 stars. However, I find it difficult to comb through my hair using this. I have short-to-medium-length fine curly hair and the tines are so thick on this, that it makes it difficult to pull the comb through my hair. If I had an easier time of it, this would have gotten 5 stars.

The current price of $6.98 is reasonable for this.',\n", + " 'I love this shower cap. It is very attractive and the black and white colors just pop. I have short to medium-length fine curly hair and take a size small in a cap. This fits me perfectly and there is a little more room for more hair if I had it. This is comfortable and does keep my hair dry in the shower. Unfortunately, I hate the way the bow looks on me.

The current price of $15.99 is on the high side of competitively priced.',\n", + " 'There are two quality headbands in this set. The headbands are SUPER SOFT that I just want to feel them all day. They look great on and I love the design.

I have short to medium-length fine curly hair and these work for me and are\\xa0even better for\\xa0someone with long hair. I actually put them over my ears so that they stay put. I have to do that with every headband I use.

The current price of $3.99 is a reasonable $2 per band.',\n", + " 'This is a large oval brush that comes with a cinch pouch. The handle has a good grip due to the silicone \"sleeve.\"\\xa0

The bristles are soft and feel great against my face. Initially, there were just a few bristles that fell out but that seems to have stabilized. I use brushes like these to apply blush. The brush head is quite\\xa0large and usable only for larger jobs.

The current price of $4.99 is excellent for this in my opinion and one of the reasons\\xa0I rated this 5 stars instead of 4 stars.',\n", + " \"There are 10 brushes in total and a carry pouch.\\xa0I really love these brushes. The geometric shape of the handles provide a good surface area for gripping each brush during application. The bristles are soft and they do not fall out of the brush. They feel great against my skin.

Based on the Amazon\\xa0site, these are the brushes in the set. Note that I cropped a photo of the brushes from the site and attached it to my review, so that one can see each brush's\\xa0use.

- powder brush
- blush brush
- angled contour brush
- foundation brush
- nasal shadow brush
- big eyeshadow brush
- small eyeshadow brush
- blending brush
- eyebrow brush
- lip brush

In summary, I love that it has more smaller brushes than larger one because they are better for detail/precision applications. The current price of $15.19 ($18.99 minus 20%) comes to $1.27 per brush which I consider reasonable. I also love the color of these brushes as they match my pink bathroom.\",\n", + " 'This set of two roll-on fragrances comes with a PU leather carry case that will hold up to six roll-on fragrances or essential oils. The lemongrass smells as it should and the protector blend smells spicy. Both of the fragrances are strong. The current price of $19.99 ($24.99 minus $5) is competitively priced for this set. Unfortunately, these scents are way too strong for me.',\n", + " 'I ordered the orange color. It is very pale and looks attractive in the tube. However, once worn it changed to a light pink on my lips. The moisturizing effects lasted a couple of hours but I personally did not like the look of the resulting color on my lips. Also, at the current price of $18.98, this is very expensive lip balm. Nivea makes colored lip balm that does not change color--so one knows what color they are getting. That lip balm works just as well and is a lot cheaper than this.',\n", + " 'I got the lavender and balsam fir set of soy candles. Each one comes in an 8 ounce tin. The balsam fir is headache producing to me and I hate it. However, the lavender\\xa0is very nice and a faint lavender scent dissipates throughout my small kitchen when I am burning the candle.

Each candle is $20 each at the current price of $39.99. Although they are made with essential oils, I still think that is too much for the set. Unfortunately, only one candle is agreeable to me.',\n", + " 'There are 12 headbands in this set and practically all of them look a similar shade of pastel pink, purple, and yellow. Only one headband is bold with an emerald green. I would have liked a red, black, and brown in this set. However, this appears to be designed for young girls or ballerinas who would love these colors.

I tried these on and the headbands are comfortable and do not squeeze my head. They also stay put. I have a small head so these would probably feed a youngster just fine.

The current price of $15.99 comes to a reasonable $1.33 per headband.',\n", + " 'This is an exceptionally well-made and beautiful brush in a travel size. The brush and handle are small, so this brush is not as easy to grasp as one that is full sized. However, It detangles and brushes through my curls\\xa0with ease. I also did not experience the typical loss of bristles I usually do with a boar bristle brush. Most animal hair brushes seem to shed for a while and then stop shedding. So far I have not had that problem.

I actually cannot believe this is priced at $7.29 because most boar bristles brushes\\xa0of this size are in the $28 to $30 range. The price, coupled with the style, finish, and functionality of this hairbrush is outstanding in my opinion.',\n", + " 'This is a beautiful compact mirror with regular and close-up mirrors on the inside. Both mirrors are small but functional. It is fashioned like a pocket watch. The clasp is solid and the finish is high-gloss like the interior mirror itself.

The saying (see below) on the outside is nice but the last two words of \"I WIN!\" may be taken wrong; it depends on the girlfriend.\\xa0

TO MY

Girlfriend

NEVER FORGET THAT

I love you

THE MOST,
I WIN!

In summary, this is a lovely gift in a nice gift box. The current price of $22.99 is competitive. I would have given this 5 stars if it were not for the last two words.',\n", + " 'I have really been getting into silicone spatulas/brush sets for applying face creams, bacitracin on a scar, etc.\\xa0 This set includes three colorful and double-side spatulas/scrubbers. Also included are two thin purple silicone pads with finger holders that are great for washing my face.

Each\\xa0double-sided wand has a flat spatula end for applying creams or gels. The opposite side has a ribbed end and another side with larger soft nubs. The nubby side is good for cleaning or also for applying mask products. However, if the large soft nubs are used, there is more cleaning involved to wash off the mask product.

The \"egg-shaped\" purple pads are great for scrubbing my face with soap and lathering up. I love the nub that allows me to hold on to this.

Overall, this is an excellent set. These are soft on my skin, pliable, and easy to hold on to. I do wish the wands were just a few inches longer for a better grip. The current price of $13.29 ($13.99 minus 5%) is competitively\\xa0priced for this set as it comes to $2.66 per item.',\n", + " 'This flat iron comes with two strange looking hair clips and a carry pouch. However, gloves were not included in the package as I had expected. It is for this reason I lowered my rating. It is deceiving to the customer to purchase an item thinking it comes with gloves when it does not.

The controls are in the center of the iron, so I had to be careful not to burn my fingers. To turn the unit on or off, I just held down the power button for three seconds. To go to the next temperature, I just pressed the on/off button quickly. This flat iron heats rapidly. The temperature selections available go from 300 to 450. I used it at 350 degrees to straighten my hair and I was able to do this relatively quickly as I have short curly hair. Also, there was no frizz after I was done.\\xa0

The clips provided are strange looking as can be seen from the photo. They work good enough to hold some of my hair but I particularly do not care for the design.

The soft sided cinch pouch is nice and holds both the iron and the clips.

In summary, this is a gorgeous iron. I love how the \"blades\" come together and there is no space in-between like some other irons I tried. Also, the current price of\\xa0$25.91 ($32.39 minus 20%) is very reasonable for this. The Amazon site says \"DUAL VOLTAGE AND COMPLETE ACCESSORIES ..... Equipped with 1x storage bag, 2x hair clips, and 1x Gloves.\" Well it was missing the last item.\\xa0Had it come with the gloves, I would have rated this 4 stars.',\n", + " 'There are two amber glass spray bottles in this set. In addition, four black labels, one stainless steel funnel, one glass eye dropper, one white marker, and two standard\\xa0black caps are included. It is important to go through all the packaging in order to find these items as I almost missed a few. Note that these are packaged exceptionally well in double bubble wrap sleeves for each bottle.

These are perfect for hair solutions, water, window cleaner, vinegar, etc., etc., etc. The spray nozzles, with a turn of the front dial, dispense a wonderful mist spray or a fine stream just like many store bought spray products. Each bottle holds 16 ounces of liquid. The amber color of the glass helps protect light sensitive products.\\xa0

The current price of $18.98 is competitive but somewhat pricey for this set as it comes to $9.50 per bottle not counting the added incidentals.\\xa0 Their [[ASIN:B08HGZXLP6 four-pack of bottles]] is about $1 cheaper per bottle.',\n", + " \"I have tried many different back brushes including this really good [[ASIN:B08HR2GBHC\\xa0Kozis brush]] and the buff puff type that lather copiously.\\xa0However, this one's bristles differ substantially. They are very fine and as soft as a cat's fur.\\xa0 The soap lathers reasonably well on the bristles and the brush feels great against my skin. It is solidly\\xa0built. It also has a rope loop to hang up in the shower.

The only reason I rated this 4 stars is because the title says this is exfoliating and I do not consider that an attribute of this brush. The bristles are too soft to exfoliate. However, it cleans well and feels great to use. I consider it 5 stars for that purpose.\\xa0 The current price of $16.99 is on the pricey side but I have no similar brush of this bristle style to compare it to. It is certainly not competitively priced with other back brushes which are about $7 cheaper.\",\n", + " 'There are four amber glass spray bottles in this set. In addition,\\xa0six black labels, one stainless steel funnel, one glass eye dropper, one white marker, and four standard\\xa0black caps are included. It is important to go through all the packaging in order to find these items as I almost missed a few. Note that these are packaged exceptionally well in double bubble wrap sleeves for each bottle.

These are perfect for hair solutions, water, window cleaner, vinegar, etc., etc., etc. The spray nozzles, with a turn of the front dial, dispense a wonderful mist spray or a fine stream just like many store bought spray products. Each bottle holds 16 ounces of liquid. The amber color of the glass helps protect light sensitive products.\\xa0

The current price of $33.99 is competitive but somewhat pricey for this set as it comes to $8.50 per bottle not counting the added incidentals.\\xa0',\n", + " 'These shower caps are really attractive in the style I ordered them in. The only issue I have is that I would have preferred them to be a bit snugger. I have a small head and short to medium-length hair, so I need a smaller cap. I am still able to use this in the shower but I have to be careful it does not move around too much.

If the elastics were snugger, I would have rated this set of three caps 5 stars. \\xa0The current price of $10.99 comes to a reasonable $3.66 each.',\n", + " 'There are six (6) velvet headbands with buttons in this set.\\xa0Each headband is narrow at only 8-3/4\" wide and certainly not as wide as pictured on the Amazon site. Also, there are buttons on each side of the ear area. When I attach my mask to these buttons, my face mask is no longer tight to my face because the slinky velvet material moves and does not stay in place.

Overall, I do not like these at all. They will suffice as headbands only and not for mask attachment. The current price of $11.99 comes to $2 per band but I do not feel they are worth that price at all.',\n", + " 'I am not sure what a balancing cream is supposed to be. Nevertheless, I applied this to my face and neck (avoiding the eye area). I like the creamy texture and the fragrance is decent. The aroma reminds me a little bit of St. Joseph\\'s aspirin. It did take about ten minutes to absorb fully, but once it did my face and neck felt incredibly hydrated.

Note that there are no English instructions on the jar or the box except for the words \"balancing cream.\" This is made in Korea and it is written in Korean. If it were not for the Amazon label, no one would know that this is a hydrating face and neck cream. Also, there is no mention of how many ounces this is but I suspect it is about 4 ounces based on the price per ounce listed on Amazon.\\xa0 The current price of $22.65 is pricey but competitive for this cream. I like it but not enough to order it again.',\n", + " 'I tried many different make-up remover products and have always been disappointed because they never remove what they say it will remove and I have to use a ton of solution or wipes. However, these surprisingly work. I used this to remove cream eyeshadow and it did a wonderful job. In addition, my lids felt moisturized. Note each cloth is infused with Vitamin E and Aloe.

There are 10 (I received 11) individually wrapped disposable cloths in each package. They come loosely packaged in an envelope, so I have to put them in a zip lock bag to store.

At the current price of 9.50 ($10 minus 5%), it comes to $.95 cents per remover cloth. I certainly would not make a steady diet of these since they are expensive, but they are perfect for that once-in-awhile situation where one needs to remove their make-up without soap and water.\\xa0',\n", + " 'There are two body brushes in this package (pastel blue and quartz pink). Each one has a silicone sleeve into which a soft sponge has been inserted. The sleeve has a loop for hanging, nubbs on one side for scrubbing, and various small ridges on the other side for light scrubbing.

I used the pink one in my pink bathroom; it matches perfectly. I showered with it and it holds the suds well. I personally like the nubbed side because it is like getting a massage while washing. My favorite bath \"sponge\" is actually a body puff (those with the netting material) because they lather up well. This \"brush\" is now my second favorite. If the suds were prolific with this \"brush\" like the body puffs produce, I would have loved this more than my puffs.

The current price of $12.59 ($13.99 minus 10%) is on the pricey side of competitive for this as it comes to $6.30 per body brush.',\n", + " \"I thought these were bath bombs when I ordered them. However, that is not what this is at all. There are 10 tiny balls of compressed flowers wrapped in various colored foils. They can be used as a tea, which is what I use them for, or they can be put in a bath. I have no idea how anyone would use this for baking as per the Amazon title.

Nevertheless, all but the purple and red balls have a purely vegetal scent. The purple and red smell flowery. I have used tea balls before and never cared for them but did like how most stayed together. However, these balls expand into many little flower particles that float in the water. If one were to put this in a bath, it would clog the drain unless the flower debris was scooped out with a skimmer. \\xa0I used the blue ball to brew into a tea and it was tasteless. I also had to use a strainer and remove the lid on my pot to keep the spout from clogging.

Besides the mess and lackluster flavor, there are absolutely no brewing instructions, no information on what tea ball is what flower. \\xa0The Amazon site has a list of the flower and the balls but does not show the foil color. It is almost impossible to reconcile that list with what is in front of me.

Shame on the vendor for not creating an insert or package label that says what is inside and which tea ball is what flower. I personally do not care for this at all and will probably throw this in the garbage.

This is not worth it to me at any price. It is certainly not a bath bomb, I can't see how it can be used for baking, and as a tea it is tasteless and messy. There is no fragrance, so its use as a bath bomb would be for romantic or ambiance purposes only.

At the current price of $9.88 for 10 balls it comes to almost $1 per tea ball.\",\n", + " \"This is a very nice set of 6 clips, 10 hair ties, and a case. The clips are strong and do hold a generous amount\\xa0of hair. I like the non-slippery feeling of the clip itself. The ties are ordinary but still functional. The reason I rated this 3 stars is because I also ordered this same set with the blue clips and tan ties. One of the clips in that order broke immediately which tells me these won't last.

The current price of $7.19 is reasonable for this set but just be aware that the clips will break easily because the plastic is not that strong.\\xa0\",\n", + " \"This is a very nice set of 6 clips, 10 hair ties, and a case. I particularly love the blue clips. Unfortunately, the first blue one I tried broke immediately as can be seen in the photo. At least I have one blue left. The clips are strong and do\\xa0 hold a generous amount\\xa0of hair. I like the non-slippery feeling of the clip itself. The ties are ordinary but still functional.

The current price of $7.99 is reasonable for this set but just be aware that the clips will break easily because the plastic is not that strong. I'm definitely annoyed about the one clip that broke.\",\n", + " 'These brushes are actually like eight combs strung together. I had to set the extra piece that comes with each brush to separate the tines. It was not easy to get the bar across the \"combs\" but eventually I managed. There are only two places the bar should be put and that is where the holes are on the back of the \"brush.\" I assembled these brushes on the lower holes. My biggest issue with these brushes is that there are only two holes to lock the bar in place when I prefer four holes like my\\xa0Heeta detangling brush (product number B0836XT7J8\\xa0since the Amazon embedded links are not working).

Once this is assembled, it glides through the hair and detangles. It works well on dry hair but even better on wet hair. I love the hard tines as it is like getting a massage on the scalp. The handle provides an okay grip but I would have preferred a silicone grip. Since the combs are separated, this brush can act as a vent brush for blow drying even though it is not of circular design. Hair can be removed easily since the tines are flat with no \"ball\" tip.

The only reason I rated this three stars is because of the hard time I had assembling the rod in place on each one,\\xa0the lack of four holes for a secure fit, and the lack of silicone grip on the handle. Otherwise they work well. The current price of $8.99 is reasonable for two detanglers.',\n", + " 'There are four tiny colorful squeeze bottles in this package that are easy to fill and easy to dispense. I like that they are portable and can hang on a keychain. These can be used for hand lotion, sunscreen, hand sanitizer, etc. However, the caps do open easily so it is possible the contents will be squeezed out inside a purse if there is a lot of movement. Secondly, the current price of $12.99 is way too expensive for what this is. I would not expect this to be priced at more than $6.',\n", + " 'I am highly impressed with this set, particularly the keychain carriers. The carriers are larger than I expected and the tie-dye colors are vibrant and attractive. The pocket in the carrier stretches to accept either the spray bottle or flip top ones.

There are six keychains with carabiners and what feels like neoprene carriers. Also included are six flip-top bottles and two pump spray bottles. The pump spray bottles dispense a fine mist depending on what I put into them (perfume, hand sanitizer, etc.). The flip-top bottles can dispense hand sanitizer, hand cream, etc. However, since they are hard, I have to hit the bottle against my hand to dispense any cream as it is not conducive to squeezing.

Nevertheless, I can put my own travel bottle (if similarly sized) into these keychain carriers. In addition, I can put in a chapstick, nail clipper, etc.

The current price of $9.99 is very reasonable for this set.',\n", + " 'Even though this is baby lotion, I got this for me. This moisturizer is lightweight, slightly creamy, absorbs rapidly, and leaves my skin moderately hydrated. Since it is lightweight, it is a perfect summer lotion. To my senses, it has a mild lemony fragrance even though that is not listed in the ingredients. This is made of all plant-based ingredients (see photo). The current price of $16 is competitive but pricey for this 6.7 ounce tube.',\n", + " 'I am highly impressed with this set, particularly the keychain carriers. The carriers are larger than I expected and the flag colors are vibrant, attractive, and patriotic. The pocket in the carrier stretches to accept either the spray bottle or flip top ones.

There are six keychains with carabiners and the flag carriers. Also included are six flip-top bottles and two pump spray bottles. The pump spray bottles dispense a fine mist depending on what I put into them (perfume, hand sanitizer, etc.). The flip-top bottles can dispense hand sanitizer, hand cream, etc. However, since they are hard, I have to hit the bottle against my hand to dispense any cream as it is not conducive to squeezing.

Nevertheless, I can put my own travel bottle (if similarly sized) into these keychain carriers. In addition, I can put in a chapstick (see photo), nail clipper, etc.

The current price of $7.10 is reasonable for this set.',\n", + " 'The current price of $7.27 ($10.39 minus 30% off) is a reasonable price for these sponges.

This set of six sponges are as good as all other blending sponges of this type that I tried before. One has a flat side for a smoother application. The pointed ends are good for more precision. They feel good in the hands and blend well and also wash well with soap. To me what set of sponges to buy all comes down to the price and the angles one wants on the sponges.',\n", + " 'This shampoo and conditioner travel-size duo (2 ounces each bottle) has a spicy aroma that is neither pleasant nor offensive but not my favorite smell. The shampoo produces a medium lather and cleans well. The conditioner is creamy and conditions well. When my hair dried, it had a sheen to it and was well nourished and my curls were enhanced.

The current price of $14 for this set is expensive. If this had an intoxicating fragrance I liked and was more reasonably priced, I would have loved it. However, this is not a set I would buy at this price.

Note that I get about four uses to this set for my short to medium hair.

UPDATE 9/22/20 - This only lasted me three uses. However, I had such trouble getting both the remaining shampoo and conditioner (particularly the conditioner) out of the bottle. They need to change this to a squeeze tube. I actually had to fill the bottle with water several times to dislodge the remaining ingredients. Also, the conditioner makes the floor of the shower or tub very slippery (almost as if I put Pledge on a floor). Based on this, I lowered my ranking from 4 to 2 stars.',\n", + " 'This single layer thin blue shower disposable shower caps are tiny. They are really for a kids head. I can barely get my hair into this. There are 120 (I did not count them) tiny blue slivers that have to be unraveled. Since they are so small, these would work best to cover the tops of small serving bowls during a picnic to keep the flies away. These are functional but I am not impressed.',\n", + " 'I do not care for these emery boards. There are 16 to the package and the boards are triple thickness compared to the standard personal-sized ones I am use to. However, the gritty surface on mine started to wear off after a few swipes of my nails over the board. Emery boards in general do not last long; however, the size and thickness coupled with the limited longevity makes me not like these. They do file the nails but they do not last.',\n", + " 'Surprisingly, I really like this mask. I already tried their\\xa0[[ASIN:B07VQY9ZP2\\xa0WeeklyPoint Cosmetic Saffron mask sheet]] and found it to be very messy and just okay. This one is less messy.

There are ten individually wrapped masks in this package. The instructions are in broken English but still easy to understand. I applied this mask to my clean face -- there are holes for eyes, nose, and mouth. It was somewhat wet but not dripping wet as their other mask. I prefer less solution, so\\xa0this was perfect. I let it stay on for exactly 20 minutes and then removed the mask and wiped off the excess. My face felt moisturized and silky. I reveled in the soft rose fragrance the entire time.\\xa0 However, the claims that it brightens the skin and protects them from wrinkles is unfounded in my opinion. On the other hand, the rose fragrance is calming and wonderful and the moisturizing effect is silky and these are my two favorite traits of this moisturizing sheet.

\\xa0',\n", + " 'This pick is absolutely terrible. It is made of flexible plastic that is easily breakable and the pick ends are so thick, they are like scaled down hammer claws that do nothing to scrap the teeth. It went right in the trash.',\n", + " \"This comes as a set and no matter what I do, the shampoo bottle will not open. This absolutely infuriates me. I was able to open the conditioner. I removed plastic seal on the top of both bottles and turned as specified on the bottle. I spent 10 minutes trying to open the shampoo. Unless I take a hammer and chisel to it or an exacto knife, I can't use the shampoo.

The conditioner is nice and has a subtle fresh aroma but without the pair, this is zero stars to me when I cannot get to the product.\",\n", + " 'This is a nice set of combs--one wide-tooth and one sort of fine-tooth with two regularly-spaced ones. I know others mentioned that they found the combs to be sharp on the edges when combing. The one wide-tooth comb has blunted tines but the other three have pointed tines. However, those pointed tine ones were not sharp on my scalp. I have short to medium fine curly hair and these passed through my hair easily (wet or dry) and I did not feel scratched. I actually like the points massaging my scalp because on the combs I received, they were not super sharp.

Unfortunately, I cannot tell if this set is wooden as it claims. It is possible they are wooden but because they are highly polished, they feel and look like plastic. I attend craft shows and it is possible to get a plastic feel and look to wood, so unless I broke one of the combs in half (which I am unwilling to do), I cannot tell. I still think the current price of $9.99 is reasonable even they are plastic.',\n", + " \"These headbands remind of Woodstock and the 60's. They are headbands the flower children would wear. The colors are muted but are perfect for casual wear. The black bands (one beaded and one not) are suitable for both business and casual attire.

These are about two inches wide and do feel relatively comfortable on. Note that the beaded bands are a bit bouffanty due to the thickness of the cloth with the extra height of the beads. Unfortunately, these are not my style. If one is in the market for this type of accessory, they are fully functional with a little bit of statement. The cloth is wrapped securely around the outer edge of the band and appears they will last a while. The current price of $16.99 is reasonable for this set.\",\n", + " 'I have used various countertop water flossers in the past such as the countertop WaterPik and the [[ASIN:B07HRNGS3Q Truwell Handheld Water Flosser]]. I love the idea of a hand held irrigator and this does work to remove most stuck debris from between the teeth. What is nice about this one over the other handheld I tried, is that there is very little splash back. However, I personally do not like that the reservoir is not removable for drying.

IN THE PACKAGE
- One reservoir attached to handheld flosser unit
- One USB cable (wall adapter NOT included)
- One instruction manual
- One standard jet nozzle
- One orthodontic nozzle (larger brush)
- One pocket nozzle (smaller brush)
- One tong scraping nozzle (what looks like a spoon)

I charged the unit fully before use. The white light on the side blinks when charging and remains steady when it is fully charged. Note the charging port is hidden behind a silicone nub below the grip dots on the top of the unit. Be careful to cover the charging port with this nub when the flosser is in use.

There is an on/off switch and a mode switch. The three water pressure modes are soft, standard, and massage can be cycled through using the mode switch prior to turning the unit on. The jet tip (or any of the other three tips) gets inserted into the top. Be careful to make sure it is seated with the notch in the groove as the first time I put it in the hole, I did not have it seated all the way. To eject, press the release button to the left side.

The reservoir IS NOT removable. Instead water enters through the small opening on bottom through which one has to fill the unit. I do not like that the reservoir is attached as I have to drain the remaining water out of that hole and leave the door open for drying. Also, the little button through which the water enters can easily break after lots of use. I personally would prefer not to have to use that hole.

I held my mouth almost totally closed during use and tried all three modes. I did not have splash back, which was very nice. Splash back is usually typical of almost any type of water flosser so to some extent I was surprised. This flosser does work to dislodge most debris between teeth but not everything because it is not super powerful but is powerful enough. I am also impressed that the manual is relatively well written; kudos to the manufacturer on this. Normally, I feel as if I am reading Pig Latin when I receive products from China or other countries.

In summary, my biggest disappointment with this unit is the attached reservoir that prevents me from drying this out easily.',\n", + " 'I purchased these type sponges before and I find them great to work with. I like to use the flat end to blend and the pointed end to highlight around the eyes or cheeks. I do find liquid foundation sink in a bit so I use these mostly with creams and some powders. Overall, these are just as good as the sponges from several other vendors I have tried in the past and these are competitively priced at the current price of $10.99 for four. I also love the four color variety.',\n", + " 'I wish I could wear these colors but most of them are too deeply hued for my fair complexion. I tried several of the colors and many make my eyes look swollen and puffy as if I had an eye infection. If I had olive or brown skin, I think these colors would look awesome. The only colors I was able to wear in this pallet are the pearl, volcano, bronze, sunset, 24k, and ash. I absolutely love the shimmer on many of these. I like that the \"compact pallet holder\" has a magnetic closure. Eye applicators have to be purchased separately. Despite this, I think $7.88 is a great price for this selection. The colors that I did apply stayed put all day.

The 15 colors starting from top row left to right and working down are:
- copper
- cinnamond
- pearl
- golden
- bronze
- volcano
- sunset
- pumpkin
- 24k
- moch
- fleshy
- mermaid
- rose
- ash
- ginger',\n", + " '[[VIDEOID:e487d57bdd82c5405085efb372c8fecd]]
This straightener is a nice metallic black and comes with a thin storage sleeve. There is a tiny instruction pamphlet included.

The flat iron feels good in my hands. I like that the cord swivels at the base so that it does not tangle.

This did an okay job on my hair. I have fine medium length hair and this mostly relaxed my curls so that my hair was more wavy that fully flat. I set the temperature to 300 for fine hair. I also tried 350.

There are several things that make this iron just okay for me. First, it is weird to have the temperature controls between the flat iron blades. There is a constant temperature key and also temperature plus and minus keys, in case the constant temperature key is not set.

The power button should be pressed to start setting the temperature and then when the LCD stops flashing, it has reached that temperature. Then the power button has to be pressed again so that the light in the middle of the plate lights up.

The plates have some space between them and they are offset a bit from each other which is the biggest annoyance to me. I guess this is why it straightened my hair only so much. This is not a bad flat iron but it is not perfect either.',\n", + " \"I am sorry I ordered this bag and am very disappointed. It's cheap, flimsy, and holds light items. Items have a tendency of tilting outward in the pockets depending on the size of the item and are at risk of falling out. The detachable clear plastic tote at the bottom is a nice touch, but that is about it. The zippers are sticky.

In my opinion this cosmetic / travel organizer will not last at all. My biggest complaint is the hook for hanging. It is not a full-size hanger hook so there are a limited number of places to hang this. It can be hung on a wire shelf with holes (like a shower caddy or closet with wire inserts) but it does not hang on a shower rod or on a closet rod or any rod much thicker than a finger.

This cosmetic bag is not even worth consideration in my opinion.\",\n", + " 'I purchased the shampoo at CVS several months ago and I absolutely love it. I have fine wavy hair and this shampoo really brings out those curls. I would definitely purchase again. I have not tried their conditioner yet but will some day soon.',\n", + " \"After moistening my face and the brush heads with water, I tested the sensitive and normal heads with both soap and [[ASIN:B01648QDS4 L'Oreal Paris Age Perfect Facial Cream Cleanser, 5 Fluid Ounce]] and the massaging head with water alone. After a one-minute "application" with any one of the brushes, I love how smooth and clean this makes my face feel.

The packages includes:

- three brush heads (sensitive, normal, and massage) and their covers which have air vents to hasten drying
- one charging base with power cord
- one brush wand that operates at 3 speed levels
- one white plastic zippered travel case
- one instruction pamphlet

PROS:

- The wand contains a rechargeable battery that last for 30 uses. The first charge takes up to six hours. It also has a 30 minute fast-charge feature that will provide 4-5 uses. By the way, I love the charging light on the base; it has a "cool" factor to it.

- There's a one minute timer that has what I call a "tripacer" (like Sonicare's quadpacer) timer built in for each of the three zones of the face. These zones are the T zone, left side, and right side. What this means is that the unit pauses ever so slightly ever twenty seconds to let the user know when it's time to move on to the next zone so that the cleaning time can be distributed evenly among zones.

- None of the three brushes were rough or extremely abrasive. The rotating and vibrating brush heads were as gentle as could be and I have sensitive skin.

- The wand with brush can be used in the shower as long as it's not fully submerged in water.

- This can be used to remove cosmetics.

- The unit comes with a 2-year limited warranty.

CONS:

- Although these brushes remove make-up effectively, I personally only like to use this on the days I do not wear makeup. The reason is that the eye area has to be avoided. I use eye makeup so I wind up washing my entire face with my hands instead as it does not make sense to me to use a brush on only part of my face.

- There are a lot of don'ts in the manual like don't submerge in water, don't use around the eyes, don't use if you are taking steroid-based medication, don't operate outdoors or where there are aerosol products or oxygen being administered, etc.

- If used daily at no more than the maximum two times per day, the brush heads need to be replaced every three months. The Massaging head (since it doesn't not have bristles) can be replaced every six months. This can get expensive. I contacted the company for the replacement price and they said they would let me know when it's orderable on Amazon. I will update the comments section of this review with that information when I receive it.

- The battery on this unit is NOT replaceable as per the email from them which I posted in the comments section of this review.

At first I questioned why would I need such a facial cleansing tool. After using this, however, I realized that I love how it makes my face feel so clean and smooth. This is not a tool I would use more than twice per week since I really hate using this to remove makeup, however, it's so gentle on my skin that I look forward to the cleansing action, mildly exfoliating properties, and the light massage it provides me all without the use of a chemical masque.\",\n", + " 'Works great for rhinestoning, made the process faster than the previous tools Iโ€™ve used',\n", + " \"This was a lifesaver for our son with an acne issue! Being a 17yr. old boy who was feeling the high school inferiority angst at a time in life thats rough enough.. bc duh, itโ€™s High School!! He hoped for a solution to improve his condition and give a boost to his confidence. We ended at a dermatologist who gave us a regiment of:
1. wipe the counter clean of all gimmicks/products
2. use a dye/scent free soap and water x2 daily
3. follow up with clindamycin 1% to dab on larger
trouble spots ONLY..!!
So, on our way to where we wanted to go... improvement was ours in leaps and bounds. Then, Covid... Then, the mask mandate!! Soon after we developed a sort of acne/rash on bridge of nose and around mouth 2โ€ due to synthetic material where the mask touches the face. Dr. said mask was compromising the skins ability to breathe and would subside after mandate lifted. Only, attending school x5 days a week 100% fully masked- didn't give skin any reprieve and with no end in sight, I went seeking help for acne irritation.

As of now, weโ€™re on the 25th day of Geologieโ€™s 30 day regiment and I am so grateful we found this product. TBH, I personally didn't realize the extent of red, blotchy and puffiness this irritation had brought his poor skin.. until after using approx. 5 days- when we noticed a decrease in the puffy/red that had gradually appeared. Over the last 2wks- it has been clearing things up a little at a time and things seem less inflamed and aggravated. What Iโ€™m most impressed with- this hasnโ€™t caused excess breakout like many other products in the past had done and Iโ€™m sure itโ€™s bc, of the compound. Nor, has it left skin overly dry.. and both of these are huge!! Iโ€™m not even sure how it does it, maybe itโ€™s witchcraft?! For comparison: a BFF uses Proactiv (as seen on TV!) with her 2 sonโ€™s for past x3 months and Iโ€™m actually surprised the results we had seem similar but, in a lot less time!?

The 2 bottles of product are easily identified and instructions are simple easy and straightforward- x1 AM/PM. I applaud the packaging as it doesnโ€™t have a feminine vibe, nothing โ€œfu-fu-โ€œ to turn teen boys away from using โ€œgirl stuff!โ€ Trust me, Iโ€™ve gone this route before- and it does matter to some! This is a non offensive clean smell and the product itself dissipates/absorbs into the skin easily after application. A few suggestions I have: leave out on bathroom counter to remind one to use daily, use fresh pillowcase every few days to keep any excess bacteria away, wash mask daily if poss. while this mandate applies.. and most of all- keep your hands away! Easier for adults- harder for teens.

As with any product there are many factors to it success.. and for obvious reasons. I canโ€™t promise it will cure all issues but, I feel confident in saying you can expect improvement (if not extinct..) end results. Iโ€™m so happy to have found this and will be looking into the entire product line for future maintenance use. Sorry so long winded.. I wanted to include details for any in a similar situation- I am hoping this info. may be helpful to someone else in need.. Be safe.\",\n", + " 'So, for a man who thinks his looks strike a resemblance to that of Anderson Cooper.. (bc, of the devilishly handsome silver fox short crew cut) mixed with a longer (3/4โ€) faux-hawk frontal vibe.. this is a great product to work with this style as it complements the cut really well! As one whoโ€™s always used hair gel (daily x30+ yrs!) itโ€™s hard to find one we have not tried. Bold Men casual- sold just under $20 for 3.3oz. Is a higher price point so, the expectations were high and happy to say, this came through impressively.

This gel has an ability to last thru the day without becoming razor sharp quills nor, a crusty-crumbly flake after a full day of wear in tear. Being one who prefers a touchable hold (the hardest combo to find btw!!) this gives that to you.. We found, unlike cheaper store bought brands- less is more! (too much will weigh down the hair) **A trick of the trade for any who want to accomplish short spikes- use less product!!

Best results came from using no more than a nickel size amount onto towel (50%) dried hair.. and finger combing into place. The hold stays movably put.. performing better then ever expected- yay!! TBH, this may take getting used too.. IF, youโ€™re norm is the โ€œfrozen gel look!โ€ Hack: one can finger style hair into place with this- then, use blow dryer on a lower setting for just a moment.. it will expedite the setting process- giving specific direction to the final look. (A convertible would do the same but.. not sure Itโ€™s feasible in winter ha ha!)

Product is thick yet, offers just enough slip to give you pliability to style before it settles. Note: color is clearโ€ฆ Itโ€™s just the container that is black! After hair is set, this absorbs vs. shellacs to the hair- letting hair have movement and touchable texture.. The scent is nice with a masculine appeal And after 3wks. of daily application weโ€™ve used approx. a tad over 1/4 of content (to give you an idea how long it will last..) thus far, washing daily weโ€™ve noticed no unwanted build up.. which is also a big deal- as this can lead to flakes/Dandruff..!! A good shampoo scrub removes product easily enough.. and paired with daily conditioner, itโ€™s not over-drying to the hair. Making the $ seem worth all the quality benefits.

This is a top quality higher end product that best fits those who have a moveable set style they like their hair to maintain throughout the day.. this can achieve the desired look and look fantastic- and does so, without all the unwanted side effects that can come with daily use of hair gel.. I hope this info can help your decisionโ€ฆ Feel free to let me know!',\n", + " 'This was a great product made to be helpful For moisturizing but, also being sensitive enough for use on a newborns skin. The baby i had ordered this for, has a unique combo- half Icelandic and half Africanโ€ฆ Creating skin mixture that needs very delicate and natural products that still can provide plenty of moisture. This product delivered!!

After noticing a few dry spots on baby skin, I did some research on how to re-capture moisture necessary.. my concern was a bit of cradle cap and the use of Emeliaโ€™s baby bath oil on the scalp. Not only was it very sensitive and user-friendly, it took care of the issue within a few days.. The other concern was the possibility of getting product in babies eyes, if added to the overall bathwater.. of course, I used my best efforts to keep this from happening- but, I found dipping washcloth into the water and wiping off faceโ€ฆ Absolutely caused zero problems- I was totally surprised and impressed!!

Knowing the African culture needs a bit of moisturizer in skin care as well as hair careโ€ฆ This has covered both needs in just this one product. Iโ€™m certain as this newborn grows we may need to adjust course and add more specific hair care regiment. As for now, this is doing just fine- and best of all leaves baby smelling amazing!!

So, if looking for a product that is gentle enough to use on a newbornโ€ฆ That has taken the precautions to keep their skin safeโ€ฆ Using only natural products- and has the ability to moisturize and even clear up cradle cap.. just a few drops of this to the bathwater- can handle the trouble spots no problem.. loving it!!',\n", + " 'Yes, it does smell good...',\n", + " \"We've been using their products for over 5 years now and it IS one of the best.\",\n", + " 'Easy to use. I suggest using the one you like least first because I messed the first ones up. Make sure not to run any hot water over them for quit some time. Other than that the second patches I used stayed on for about 3 days until I noticed chips.',\n", + " \"Flushes the residual food particles like a ToTo toilet flushes. Off the bat this works excellently, and it is when you recharge them that they just stop working. I have recharged this once now, and so far so good, but this isn't my first purchase. Whilst it is works, it is a powerful addition to self care.\",\n", + " \"Starters, I LOOOOOOOOVE tea tree scent, strong, but not overpowering or nasty in synthetic way. As conditioner, really liked that the product didn't have greasy or heavy feel as I applied it to my hair. Nice smoothness after drying, liked the feel,of my hair, but no major fragrance afterwards, which I like. Treats my scalp in good condition too.\",\n", + " \"it's missing bristles and it's splintered on the back! i found one at target for $5.\",\n", + " 'Perfect fit and perfect quality.',\n", + " 'Love this stuff, works well, nice light scent. Decent size bottle, good price.',\n", + " 'These work really well. These are better than Biore strips. They are a little difficult to get off the clear sheet, but they stick well and they really clean the pores.',\n", + " 'I usually use the orange Real Techniques makeup sponge. The diamond sponge is pretty much the same, just a different color and shape. The diamond is much cuter. However, the orange sponge is an overall better shape. I mean, this one will do, but the hard cut edges vs. soft curves make it a little less of an ideal shape for use. But it makes up for that in being really cute.',\n", + " 'Happy I can still find these for my mom good quality',\n", + " 'I love holographic nail polish does it work definitely the only issues I really have with it the price and the size of the bottle there really is no reason for it to be in such a small bottle',\n", + " \"Just nail polish despite numerous attempts just will not put the cat by Design on in anything that is almost so faded you cannot forget it cannot be blamed on the magnets because I have probably close to 25 magnets and I have run into the same problem with all of them follow the instructions to a T and it's always very very faded\",\n", + " \"And here we have another product that I am still not thrilled with your hair and your hair is close to yourself and what happens when the plastic cap comes off the end and the metal snap and now you have a big chunk of metal poking you in the head yeah I'm not happy at all I have not even contacted the vendor because I don't want sound mean to them how upset I am with the quality that is not here. Replacement would be nice\",\n", + " 'Terrible quality. Did not even last 18hours.',\n", + " \"We mostly use essential oils in diffusers with only a little concern for holistic effects. But we do run peppermint and lavender for stress relief. We have been very happy with these in the diffuser. They smell great and come in nice little bottles. It would be a great little gift set although the box is not overly ornate. I can't really do better to describe it than to say it is a decent intro set.\",\n", + " \"We discovered Essie nail polish a while ago and it quickly became my partners favorite. But that was the Gel Couture line which has been known to stand up to entire canoe trips into Minnesota's Boundary Waters. This is truly good nail polish, but as she says, "this is more for people who do their nails daily or at least don't expect it to last through a hike."

We did like the Let it Glow Pink color, and we like the brand, but they set their own bar high. This is definitely a good polish, just their other line is better.\",\n", + " \"This deodorant has a fairly strong scent that lasts a long time. I haven't notice any staining on any of my tshirts and have been using it consistently for about 5 weeks. If I had anything critical to say about this product, it might be a little too strongly scented, but it works and I've been happy with it.\",\n", + " 'It looks awkward when put on your head and itโ€™s a lot shorter and curlier than itโ€™s advertised. You also have to style it yourself.',\n", + " 'I really like the product and have been searching for other colors.',\n", + " 'One of the tubes seem to be a less full than the other two and the wrapping around all 3 is coming unglued',\n", + " \"I absolutely love this wig! It is sooooo soft and it looks and feels real! It's easy to install. I love the packaging it came in which included eyelashes(thank you)! The box is very nice, durable and reusable. I'm a sucker for reusing nice packaging to store my wig when I'm done with it for a little while. I highly recommend this wig and this brand!\",\n", + " \"The shower sponges are just slightly smaller than the average ones sold, however, I'm sure with daily use they will expand fine. So far, so good. Sent in a zip-lock style bag to maintain cleanliness, nice touch. No choice as to colors, but I received two green, two purple and two blue, with a traditional rope loop for hanging. Pleased with purchase, will update once we've used one for a length of time.\",\n", + " 'I purchased these items for creating essential oils products for cleaning, health, and first aid. These bottles are beautiful cobalt blue bottles, and the perfect size to fit into medicine cabinet. I love that they came with labels.',\n", + " \"This is just okay for what I needed it for. I know the ridge around it has a purpose, but, for me it didn't work. However, I find that is well made. I am using it to set my potted plants on. I ordered it for shoes, but, I also think it needs to be a little heavier for that.\",\n", + " 'This doesnโ€™t leave my hair as soft and moisturizing as the mask, but works great.',\n", + " 'Wonderful for skin and hair, really works!!!',\n", + " \"Excellent color for my fair skin. The Nude color is just right in winter months, the Buff Beige for the summer months. Applies easily and absorbs and drys quickly.

The primer was a delightful surprise that my skin loved.

The sponges were playful but clunkier and firmer than I like.

The plastic tote is a nice idea but I didn't care for how cheap it looked and felt.\",\n", + " \"Not only does the soap feel like luxury on the skin it looks like luxury. I am very happy the scent is subtle and unique. The lather is rich and rinses clean. Don't miss this.\",\n", + " 'You could use this as a hand soap as well as a wash to use in the shower. Washes away easily, lathers up nicely and comes in a attractive plastic bottle that is good enough for company. I could not be happier.',\n", + " 'Comes fully charged. 100% waterproof. There is only ONE 3 headed grinder. The packing list on the product page lists \"3 x 3 in 1 Grinding Heads\", so I believed it came with 2 replacement heads, The marketing materials show you how to replace the head, however I am unable to find where to obtain them. Hopefully by the time these wear out in a year they will be available.',\n", + " \"I LOVE the colors! I have very thick hair so hairbands are almost always snug and this is the same width as most hairbands. Vibrant color. The buttons are placed EXACTLY where you need them. The seller includes extra buttons. The buttons are not removable but when you take the mask off you can flip the hairband so the buttons face inward so you don't see them. I like the big white buttons, they give me a retro 1940's look.\",\n", + " \"I can get 750 J&J Qtips for a $4.64. So this all comes down to the environment.

The J&J swabs come in plastic container and these come in a box which is kinder to the planet.

These have a bamboo stem and the J&J are plastic! (I always thought they were paper!). And I am LOVING how sturdy the stems are: they don't bend, not that I use force when using, it just makes for a sure grip.

I did a side by side and the tips are the same thickness.\",\n", + " \"Terrific list of ingredients, this stuff is the real deal. I could feel immediately on application that this product contained Retinol as advertised and not a watered down 'serum' variation. Remember to moisturize after. This is a terrific product to use as your Retinol go to.

I got a lot of info from Marie Claire article by Katie Thomas 'Retinol - the only ingredient that will reduce wrinkles'

Your skinโ€™s collagen level starts to deplete at age 25.
Retinol helps with skin elasticity, wrinkles/laugh lines and pigmentation aka age spots.
Retinol is a derivative of vitamin A.
Start low ( 0.3%) increase to 0.5%. 1% is best but only available with a prescription.
When you first try your skin may get dry, red & flaky.
Only use twice a week, gradually increase to daily as desired.
Apply a pea-sized amount at first and increase amount and % as negative side effects decrease.
Use anytime day or night, just use sunscreen after if going outdoors.
Anywhere you see signs of aging is a good place to apply, face, arms, hands, legs, neck.
Avoid the skin around your eyes as it is too delicate.

Aqua/Water/Eau,
Caprylic/Capric Triglyceride (emollient/natural moisturizing factor/replenishment/texture),
Glycerin (hydration/natural moisturizing factor/replenishment),
Dimethicone (conditioner/silicone),
Glyceryl Stearate (emollient/emulsifier),
PEG-100 Stearate (emulsifier),
Polysorbate 20 (emulsifier),
***Retinol (age delay/brightener),
Phenoxyethanol (preservative),
Sodium Hyaluronate Crosspolymer (hydration/replenishment/restoration),
Carbomer (thickener),
Cetearyl Alcohol (thickener),
Caprylyl Glycol (conditioner/emollient/preservative),
Ceteareth-20 (emollient/emulsifier),
Ethylhexylglycerin (preservative),
BHT (preservative), Allantoin (sooth),
Disodium EDTA (pH buffer/preservative),
Hexylene Glycol (preservative),
Sodium Hydroxide (pH adjuster),
Pentylene Glycol (solvent),
BHA (preservative),
1,2-Hexanediol (preservative),
Beta-Glucan (antioxidant/sooth),
Myristoyl Pentapeptide-8 (age delay)\",\n", + " \"but it isn't certified organic, so is it? I have Aloe plants, but when traveling having Aloe Vera in a bottle is terrific. Also if you are looking to make your own hand sanitizer this is great to add to isopropyl alcohol.

Sdara is a Canadian Company that has been around since at least 2016.\",\n", + " 'I smell like furniture polish, it was piercingly unpleasant.',\n", + " \"It's like having your own Aloe plant in a bottle because the first ingredient is Aloe. We do have an Aloe plant in our home. The bonus is the vitamin E and Hyaluronic Acid (improves skin elasticity). This works great on sunburn!!!

In a pinch you can use this and mix with isopropyl alcohol (30/70 mix) and make hand sanitizer.

This really well packaged to prevent leakage in transit and you can reuse it to keep little fingers from depressing the product.\",\n", + " \"The Removable/detachable Water Tank is not removable nor detachable. I studied the user manual and no mention on how to remove it so you can clean it.

It doesn't come with an adapter so unless you have an extra you will be charging with your laptop. FYI will not operate while charging.

The full water tank lasts for 50 seconds of continuous flossing.

A Full battery will last 30 minutes before needing a recharge. Charging time:4-6 Hours. Charging voltage:5V.
Cleaning modes are gentle/standard/pulse massage. High pressure water pulse, 20-140PSI water pressure. ** Make sure to not lose the little white tab that covers the charger port - you'll need it to keep it waterproof.\",\n", + " 'This is the real deal. Designed for naturally curly, wavy or grey hair, or any hair type that needs deep conditioning. I have 50 year old curly highlighted Irish hair. My styist actually noticed how soft it felt and controllable it looked. The product calls it Curl Rescue with Keravis Ultra Conditioning Formula for Curls. No Sulfate or paraben; alcohol & cruelty free. With keratin and Vitamin B5.

It is doubled packaged inside a mylar container to control any spill in transit.',\n", + " 'Unbeatable! The next best thing to going to your dental hygenist daily. I have been using the same one for 10 years, never needed to buy a new one. I switch the brush out every 3 months or so. I can still remember the epic difference between my regular toothbrush and this. a small amount of toothpaste does a great job. Worth Every Penney, do yourself a favor and get one today.',\n", + " 'Very pleased with iron. It makes great curls and can also straighten hair when you want different look',\n", + " \"Love the way it sticks to the counter! It's a great size for me. I mix all of my dog's food in it, then put it in their individual bowls. I'm going to need this bowl in all different sizes. It's made very well!\",\n", + " 'Perfect !',\n", + " 'Great for acne prone skin',\n", + " 'Itโ€™s great, feels perfect and does not permit my hair to get wet!',\n", + " \"The wig in the picture is not the wig i received. It's lighter in color, part is on the side not in the middle and does not lay right.\",\n", + " \"If you find yourself reaching for lip balm throughout the day, you may want to upgrade to a lip mask. It works either at night or during the day. This one has a light vanilla scent that can be used by anyone. It doesn't just coat your lips. It actually nourishes and gently exfoliates. A little goes a long way. It makes a good base for other lip products. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided helps make your decision a little easier.\",\n", + " \"Body illuminator are great at highlighting your gifts and blurring flaws. I like that this formula is made for sweaty conditions. Considering you use products like this mostly in warm weather, it makes sense to offer this feature. It's easy to apply and resists transfer. The coverage is buildable. You can shimmer a little or a lot. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided helps make your decision a little easier.\",\n", + " \"There's a Chinese actress who attributes her perfect skin to twice-daily sheet masks. After using one per night for several months, I totally believe they work. This mask is the best for hydration. It can be used by all skin types. The sheet is soft and flexible. You can stretch it as needed. I always stretch the eye holes since I have larger eyes. It also prevents the serum from dripping in your eyes. Another tip is to rub the mask on the backs of your hands before throwing it away. That skin needs special care also. The best part about this set is that you get so many masks. You can try using one nightly to see how it changes your skin. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided helps make your decision a little easier.\",\n", + " \"I'm a true skincare addict. I really like these holiday sets. They're a good way to try new products. Caudalie is a cult favorite for a reason. Their products are made from the grapes in their vineyards. You get all the benefits of the resveratrol in pretty packaging. This set comes with a moisturizer, serum and foaming cleanser. They come in travel sizes, so it's just enough to decide whether you like them or not. This set is a great value. It makes the perfect gift. As a note, my box was a bit banged up. The products weren't properly glued to the base, so they came out in the shipping package. Other than that, I highly recommend this set.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"With winter approaching, it's time to start thinking about cold-weather skincare. This moisturizer is a good choice because it's a blend of several skin-loving oils like argan, coconut and macadamia. It's fairly lightweight but it protects and hydrates like a heavier cream. It can be used both day and night. The packaging is pretty enough for display. It can be used by all skin types. I highly recommend this product and the entire line from this brand.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"If you have any level of melanin in your skin, you know the struggle with hyperpigmentation. Any red spot that comes out on my skin eventually turns brown. This moisturizer is deeply hydrating in addition to being a powerful brightener. It helps to get rid of blemishes and dark spots faster than most OTC treatments. Use it twice per day for best results. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"A healthy barrier leads to healthy skin. This serum helps to repair your skin's natural barrier, locking in moisture and blocking bacteria and irritants. It contains niacinamide which helps to reduce inflammation and redness. Centella heals skin and makes it more resilient to environmental damage. The serum is fairly lightweight and absorbs quickly. It's safe to use twice daily. It's ideal for dry, irritated or acne-prone skin. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"A balance pH level is important for healthy hair. This conditioner helps to balance your hair's pH level in addition to repairing damage. It's also very hydrating. It has just the right amount of oil to tame curly hair. The scent is fresh and lightly herbaceous. The texture is on the thicker side but not like a deep conditioner. It's a good overall product for all hair types.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Sheet masks are my favorite way to give my skin special treatment. You get six masks in this set. Three masks are aloe-based, three have pomegranate extract. Aloe is well known for healing and soothing skin. Pomegranate brightens and plumps. Each mask is soaked in serum. There's enough to cover your neck in what's left in the package. The masks are so juicy that the serum may drip down into your eyes. If you have large eyes, widen the eye holes with your fingers so the top of the hole is at or above your brow. If you refrigerate the masks before application, you'll get the benefit of cooling your skin's temperature and reducing inflammation. I highly recommend this set.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I'm a curly girl. One of the constant struggles with my type of hair is that it may look dull sometimes since it's so dark. This shine spray is like a makeover in a bottle. It adds instant shine and makes it look like you had a color touch-up. The formula is lightweight and non-greasy. It has a light, somewhat floral scent. I would definitely spend my own money to purchase this product. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"One of the reasons skin starts to wrinkle as we age is that we make less and less of the natural oil that keeps skin looking youthful. It's one of the reasons why people with oily skin seem to be ageless for so long. This serum is a good way to supplement what your skin lacks. The oils in this blend are all high quality. Some are slightly unexpected in a skincare product. The texture is lightweight and easily absorbed. It doesn't just sit on top of the skin. Your skin will feel softer immediately and you'll see more improvements over time. Dr. Denese is a trusted brand when it comes to care for aging skin. Whether you're trying to slow the clock or reverse it a little, this serum should be part of your daily skincare routine. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I like to keep extra spray bottles on hand. They're useful for so many purposes. I like to put all of my liquid hair products in them because it's much easier to use a trigger sprayer than a pump when your hands are wet. You can also use them for cleaning products or fabric sprays. This set is a good buy.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I use lots of sheet masks. Most leave your skin a little sticky when the serum dries. This mask works differently. The sheet locks the moisture in and doesn't leave a sticky residue. It's a great hydration and brightening mask. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I really like that this mask includes special patches for the eyes and smile lines. If you're over 30, you'll appreciate the extra help. You apply the patches first, the the sheet mask. I keep all of my sheet masks in the refrigerator. You'll appreciate the cooling and anti-inflammatory effect if you do so with this mask. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " 'Sheet masks are my favorite part of my skincare routine. They give you time to indulge in \"me time\". These masks work to both hydrate and treat skin. The material adheres to skin well and stretches if you need a little extra coverage. The serum brightens skin and gets rid of dullness. Your skin will look plump and radiant after the first use. I suggest keeping the masks in the refrigerator prior to use. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I\\'ve provided makes your decision a little easier.',\n", + " \"These vacuum spray bottles are very easy to use. They're especially useful for cosmetic products that contain ingredients that start to degrade when exposed to air. They're ideal for toners, hydrating mists and even essences. They pack well and are leak-resistant. This is a great buy.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I really like this moisturizer. It's lightweight and creamy. It has a light cucumber scent that I find refreshing. It's a powerhouse at deeply hydrating parched skin. It also locks in moisture to keep skin looking fresh. It contains botanicals that soothe irritated or inflamed skin. It's ideal for those with acne, rosacea or eczema. You can use it as both a day and night cream. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"If you're over 35, this serum is a must. It contains two powerful skin-saving ingredients. Vitamin C keeps skin bright and radiant. It protects skin from UV damage. It boosts collagen production and helps fade dark spots quickly. Hyaluronic acid helps your skin draw moisture from the environment. It reduces the appearance of fine lines and wrinkles. It's hard to find a high quality organic serum like this. I highly recommend this serum and the brand.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I love water cream moisturizers, especially in warmer weather. This one is light as a feather, but provides intense moisture. It leaves skin feeling silky and refreshed. You don't need much, so this jar will last a while. The formula is good for all skin types, but I especially recommend it for oily skin. You can use it both day and night. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Warm weather means unruly hair if you're a curly girl. Headbands are a staple for me. These have a fun tropical feel. They're very soft and stretchy. They should fit most heads. I'd get a couple different sets of these because I like them so much. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"If you have eczema, rosacea or psoriasis this serum will soothe and hydrate your skin. The cica (centella asiatica) is known to treat and heal irritated skin. It also helps to reduce redness and inflammation. Use twice daily for best results. I highly recommend this serum.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"This mask set allows you to choose exactly what your skin needs on any given day. There are five types. There's one for hydration, firming, brightening, healthy aging, and pore detoxing. For best results, leave the masks on for at least 15 minutes. Use the excess serum on your neck. I highly recommend this set.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Every mascara claims to be new and different. This one actually lives up to the hype. The fibers have a novel shape that really makes your lashes POP. If you're not a fan of falsies, this is a great alternative. The formula isn't waterproof, so keep that in mind. I HIGHLY recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Native makes some of the best natural deodorants on the market. They're just as effective as the drugstore brands. I like this set because you get three different scents. My favorite is the peony. The scents are all fresh and light. They won't clash with other fragrances you wear. This set is perfect for gifting. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Tea tree is one of my favorite essential oils because it has so many uses. It helps acne blemishes to heal quickly. It can be used as a topical antibiotic. You can add it to hair and scalp treatments to promote growth and scalp health. It's also a calming scent when used in a diffuser. You'll probably find more uses for it over time. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"This moisturizer is ideal for most skin types. It is fairly lightweight and provides deep hydration. It's especially good for sensitive or reactive skin. It's a good choice for those with rosacea, eczema or acne. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I pretty much chose this product based on the shout-out to Arrested Development. This is a loose pigment with a super-fine texture. I opened it when a ceiling fan was on and it went flying. You'll want to use this with a mixing medium to make it stick. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Hyaluronic acid is really one of the best skincare ingredients to use for hydrated skin. It keeps skin looking dewy and plump. You can add it to your moisturizer or apply it directly. Add a few drops to a mud/clay mask to make it a balancing treatment.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"This set makes it really easy to travel with your favorite beauty items. The dispensers are attractive and very easy to fill. It comes with labels so you know what's in each section. You can continue to reuse them for different items if you rinse them out. I highly recommend this product.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"Sweet orange is one of my favorite essential oils. It immediately makes me feel energized and refreshed. This body wash is the perfect way to start your day. The scent will perk you up and get you moving. The formula is very moisturizing and won't strip your skin. The fragrance is unisex, so it would make a good gift for women and men. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"If you're reading this review, you probably already know the anti-aging benefits of collagen. This mask has a high-potency form of collagen along with a special delivery system to help firm your skin. The mask is in two parts, so you can get a better fit than a regular sheet mask. I can't say it performs miracles, but it's definitely worth a try.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I'm trying to do a better job with paying as much attention to the ingredients in my skincare as those in my food. This is a great natural cleanser. It's very gentle and is good for sensitive skin. The lactic acid hydrates and gently exfoliates over time. You won't need a science degree to understand the majority of the ingredients. This is a great clean beauty cleanser that I highly recommend.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"As a curly girl, I'm very familiar with using hair oils. This one is an organic blend of argan oil and shea butter. Both are excellent for hair. You can use this as a shine booster, hot oil treatment, or anything else you choose. You could even try it as an overnight treatment. It's a great product. I highly recommend it.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"These sheet masks are great for dry or dehydrated skin. They're especially good to use in cold or dry weather. The masks contain an extract of oolong tea and hyaluronic acid. Your skin will look dewy and radiant after 10-20 minutes. Make sure the mask is smoothed over your skin. If you have a jade roller, it's nice to use it over the mask to increase absorption. I highly recommend both this mask and the entire product line.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"A good hand cream is essential. This one is excellent. It is thick and creamy. It's very moisturizing and is packed with skin-loving botanicals. It's fragrance-free in case you have allergies or just prefer the unscented option. This is a high-quality hand cream that's great to keep in your bag.

Thanks so much for taking the time to read this review. I hope the information that I've provided makes your decision a little easier.\",\n", + " \"I'll admit it. I cheaped out on my spray bottle. I'm glad I upgraded. This is so easy to use. It makes wash day and styling so much easier. I only wish it came in a larger size. I highly recommend this.\",\n", + " \"This is the best moisturizer I've ever used. It smells like a tropical vacation and leaves my curls plump and shiny. It's like the Holy Grail of natural hair products.\",\n", + " 'More narrow than I thought and def flimsy material. Also thought it would stick better but it didnโ€™t. After the water starting filling the tub, they started getting lose which defeats the purpose. Total waste of $ for me.',\n", + " 'It was not at all what I thought was advertised! I was expecting a tinted lotion! As a plain lotion, itโ€™s still doesnโ€™t get any stars! Itโ€™s very thin and runny! Sorry Joan!',\n", + " 'I love this hair bun maker, it is the easiest one I have used!',\n", + " \"20 minutes of fragrance nothing more. $30 plus dollars for this!! I wanted Donna Karen cashmere mist but the shipping took too long. Wish now I would've waited. It does nothing for sweat absolutely nothing!! It's so small too.\",\n", + " 'I have for years dealt with dry, cracked heels, and I have tried a number of things to correct the issue. While my heels havenโ€™t hurt or anything, they have been ugly. In a search for solutions, I found this foot scrubber and decided it was likely going to work better for me than a foot rasp, and I ordered it. Itโ€™s a great tool and it works well, though I do offer some caution for those who havenโ€™t worked with a foot scrubber or rasp in the past.

This is an odd-looking instrument, vaguely similar to a comma in shape. The scraping side somewhat resembles a mirror with a patterned rough edge. It feels a lot like an emery board though it has more of a โ€œbiteโ€ to the surface, if that makes sense. The overall size and shape make it easy to grip and hold, even when wet.

The first time I used it, I scraped away a fairly large amount of dead skin, to the point that I had feeling in parts of my heels where I have had no feeling for quite some time. It left my heels soft, pink and looking much better. However, I did discover that one can overdo, and I had nicked myself on each heel in one or two places, just enough to require blotting but not enough to really be a concern (it was less serious than a cut while shaving).

I discovered the following day what happens when you remove too much dead skin and donโ€™t put enough lotion on an area that deals with weight and stress โ€“ my heels split in a couple of places and I ended up having difficulty walking without pain for a couple of days. I had put high-quality lotion on my heels, but apparently not enough. That was entirely my mistake, and it was a painful one.

After that finally healed up, I tried again. I have fallen into a daily routine where I gently scrub my heels for a couple of minutes each, then apply lotion. My heels now look much better, theyโ€™re not splitting when I put weight on them, and I have avoided nicking myself. At least in my case this is not a tool that gets used intensely every couple of weeks, but rather it is a daily tool that gets used very gently.

I got curious and put this tool under a digital microscope to see what the rough surface looked like. The roughness resembles a series of crescents, not dissimilar to a rasp, but much more fine.

This thing really works and it does a good job. Itโ€™s slightly more expensive than the average foot rasp but it seems to work well. I do recommend using some caution when working with this instrument as it is possible to overdo if not careful, which is probably very true of any tool of this type.',\n", + " 'I selected this little hair remover/shaver for my wife, to replace a trimmer she had simply worn out over time. This trimmer is a bit different than many of the others I have seen of its type which look more like mascara applicators. After one use, my wife is very pleased with it.

This trimmer is similar to a rotary shaver that men use to shave (except one head instead of three) and is similar in size to a glue stick. It runs on a single AA battery and is relatively quiet.

After figuring out how to use it, my wife trimmed a single hair and was pleased, and then did something that really surprised me โ€“ she used it to dry shave her whole leg. It did a surprisingly good job and actually left her leg smooth, but it took a really long time to finish. This is absolutely not the job for which this little trimmer was designed, but apparently it will work in a pinch.

Compared to other trimmers she has used, this one is very gentle and when itโ€™s turned on it doesnโ€™t sound like itโ€™s laboring like some of the others do.

Overall, this is a decent little hair trimmer, designed for facial hair. Itโ€™s small, quiet and works well.',\n", + " 'Purchased these 15 months ago and all are still completely functional. Strong Zippers, wide opening and easy to clean. Use for storage around the house every day. We Highly recommend this brand InnoGear and this product. Sturdy construction!',\n", + " 'The curved ends on almost all of these is not curved & angled enough to twist & clasp, at all. I cant get them to clasp, even when they are not in my hair. This was a huge waste of money.',\n", + " 'Adorable! I love the super soft fabric and the quality stitching. I did not realize these were not stitctched to appear to be tied, which I really like- Mommy actually ties it to create a custom fit for their babyโ€™s head. Perfect!!! Hope to see more sets, specifically solid colors (pastels, primary colors, neons) My daughter and daughter in law love them.',\n", + " \"Don't waste your money,I have power cord issues all the time and it continously stops on me.
I would not recommend this for beginners because I find it to be very frustrating.
This product needs a lot of improvement. I'm buying a new today from another company...\",\n", + " 'The best hairspray I have found for my fine blonde hair. Not stiff and you can style after spraying .',\n", + " 'Dry, crumbly and impossible to even get on. Smells were not my favorite. Wonโ€™t buy again.',\n", + " 'This is a joke. They do not work. Do not waste time or money.',\n", + " 'Smash box lipstick is always buttery smooth. All their shades have a rich longer lasting pigment, even the nudes.',\n", + " \"The lashed are pretty but the band is too wide, it covers too much of the eyelid. Also the way it's packaged makes it difficult to remove from plastic casing and tears the lash strip.\",\n", + " \"The lashed are pretty but the band is too wide, it covers too much of the eyelid. Also the way it's packaged makes it difficult to remove from plastic casing and tears the lash strip.\",\n", + " 'This hair is the worst ever..all the ends came down',\n", + " 'My granddaughter wanted this and I was skeptical. But being grandma I ordered it! She loves it. Super easy to use and looks great on. The polish lasts well. Great value for the price.',\n", + " 'when I applied a little pressure the wheel stopped spinning. Not enough power.',\n", + " \"These look and fit BAD.
Fake looking.
Not dentures fake- Halloween fake.
Plus they don't conform in your mouth. They are bulky. They require major adjustments with power tools to fit properly. These are a joke. If your getting them for a prank or to play dress up, I guess theyโ€™d do.
If you need a decent temporary smile that looks and feels good, go with Imako.\",\n", + " \"This is far too heavy and greasy to be applied on the eyes. It earned stars because it wasn't a total waste; it will work as a lip balm.\",\n", + " 'Feels great on, but the colors are very very bright. In the end, these are too intense of a color for me, so I ordered the clear version, which I LOVE, and use every day.',\n", + " 'To strong for my liking so I have to my daughter she likes it',\n", + " \"Aeroblend is The Best airbrush foundation. It looks just like my natural skin when applied. I purchased my Aeroblend system in November, and it's Wonderful! Since November, I have tried Luminess, Belloccio, and Aeroblend foundations. I had hoped I would like Belloccio because it's half the price, but it could not compare to the Aeroblend Foundation. The Luminess was too sticky, like it never set. The Aeroblend looks Absolutely Flawless. It takes minutes to do my makeup now, and so many people have asked me about my skin. I am so glad I purchased my Aeroblend system!\",\n", + " \"very impressed with this! It doesn't fry my hair, my hair feels sleek and without static electricity.
Also I didn't know it doubles as a flat iron, 2 in 1 product. love it!\",\n", + " 'hard to find black, i love it',\n", + " 'So comfy',\n", + " 'There is no plug for the water to help freeze instead of leaking out, not freezing well!',\n", + " 'Fun wigs for our wig & wine party',\n", + " 'The brush is wonderfully made. Its thickness really helps with messaging the scalp .',\n", + " \"This moisturizer is so yummy! It's light weight but super hydrating! It smells so yummy! I'm really picky and I love the scent! It has great ingredients I just wish they had another option for a bigger bottle ๐Ÿ˜๐Ÿฅฅ๐Ÿฅฅ๐Ÿฅฅ๐Ÿ’ I used this moisturizer on my boyfriend's face and mine and we both loved it :)\",\n", + " 'These shiny facial massage cryo sticks chill quickly, and I love that they come packaged within a clear plastic storage case with an instruction card! You can actually hear the anti-freeze/non-toxic liquid gel floating and bobbing around inside each stainless steel spoon/orb, and I love the ergonomic shape of each tool! The brightly colored turquoise handle tips help protect my fingers from the cold, and these futuristic-looking devices sit and balance nicely on various parts of my face! They do a great job of reducing swelling, puffiness, and fluid retention, and I think theyโ€™d make an affordable and unique gift for fans of at-home, cold therapy techniques! โ˜ƒ๏ธ',\n", + " 'I absolutely love this dual-headed face roller!! Itโ€™s gorgeously colored, easy to hold, attractively packaged, and competitively priced. I especially love using it after Iโ€™ve cleansed my skin and applied moisturizer, right before I start putting on my makeup. It instantly helps depuff my skin, and it seems to enhance the smooth coverage of every cream and foundation I use immediately afterwards. It has definitely become part of my daily skincare routine, and the aluminum alloy rollers are super smooth and manage to apply the perfect amount of weighted pressure!',\n", + " 'The lavender bath bomb and rose-scented bath bomb and soap bar all feature light, feminine scents that pair nicely with the included candle! The stainless steel cup seems well-constructed and nicely sized, and the various tools and bottle openers are an appreciated bonus. This boxed set is ready for gifting and even comes with a blank card that can be easily personalized to some lucky recipient. I think this grouped assortment offers a nice variety of different and relaxing products that most customers would enjoy!',\n", + " 'Iโ€™ve used many Korean face masks before but never a hair mask specifically! I love that the treatments come packaged in individual pouches (which makes them perfect for travel), and I like that they come as a boxed set. After shampooing my hair and brushing it straight, it tucks easily into one of these pre-filled bags, and itโ€™s simple enough to squish and massage the conditioning product around. I usually keep one on for a couple of hours, and it seems like the body heat associated with activity and movement helps the essence really penetrate every strand.

The attached straps are easy to affix and release, and the product washes out smoothly enough and manages to leave my hair super shiny too! I love that this formula contains a blend of kernel oil, fermented yeast extract, and soybean seeds because they mix nicely with all of the floral notes and botanical aromas! These deep-conditioning treatments seem to work wonders for my color-treated and often heat-styled hair!',\n", + " 'I like the details of the twist-front designs on these stretchy headbands, and all of the fabrics feel soft and lightweight. Each one is easy enough to wash, and they come in a wide range of attractive colors, so I usually leave a couple in my car for unexpected hikes and impromptu workout sessions. Theyโ€™re also great for holding my hair back during morning and evening skincare sessions, so Iโ€™d gladly recommend this multicolored variety pack to others!',\n", + " \"I think this is a great set of utilitarian beauty tools! If you've ever tried to apply a goopy face mask with just your fingers (looking at you gold-infused charcoal paste), then you know the struggle that often comes with scooping up products and then trying to spread them evenly before they start to dry in place. These bendy silicone-tipped spatula brush sticks and paddles streamline the entire process!

All of the tools are lightweight, easy to clean, and they seem to be fairly durable! I love the candy-colored palette of pastel hues, and the various textures and tips offer plenty of versatility and flexibility. They are also great for hygienically scooping up globs and dollops of various creams and moisturizers that need to be kept as sanitary as possible for repeated applications. I'd definitely recommend this tool set to others!\",\n", + " 'These medical-grade silicone scar removal sheets are so versatile! Acne scars, burn scars, and post-surgical scars all benefit from the consistent application of this painless product, and I love that itโ€™s a viable alternative to topically applied creams and gels. I love that the flexible material comes rolled up like tape, and I appreciate that it can be cut and trimmed into custom shapes and sizes. The chosen flesh tone would likely suit many users, so it at least provides a certain degree of modest skin camouflage.

The silicone component brightens, hydrates, moisturizes, softens, and repairs damaged skin, so repeated use truly does seem to make a noticeable difference. Scars slowly start to fade as the skin regeneration process kicks into high gear, and these sheets are actually reusable, washable, flexible, breathable, and easy to apply!',\n", + " 'I have tried and tested many rollers and scrapers recently, so I inspected this duo closely. The gold hardware on this dual-ended roller seems reliably attached, and both ends roll freely, but the larger end does seem to have a small issue that causes it to bump with each revolution, preventing the rolling motion from being completely smooth and silent. That being said, it still adequately applies smooth and even pressure to the face with each systematic use!

The gua sha scraper exhibits some scattered scuffs and scrapes, and the edges and โ€œvโ€ angle have some rough, white areas they donโ€™t look perfectly polished, but all natural stones have imperfections to some degree. This set comes attractively packaged, and it seems to be affordably priced, so it might be a great choice for consumers looking for a starter facial set!',\n", + " 'Iโ€™ve greatly enjoyed using this organic clover honey face mask! The texture is smooth and dreamy, and it seems to offer me a very nourishing skin treatment every time I use it. It rinses away cleanly after 20-30 minutes of wear, and I also love that this bee-powered skincare product is made in the USA, so Iโ€™d definitely recommend it to other consumers in search of a honey-infused facial concoction! Oh, and both the glass jar and paper box are recyclable, so itโ€™s an eco-conscious pairing all around. ๐Ÿ‘๐Ÿฝโ™ป๏ธ',\n", + " 'This multicolored variety pack of headbands is so eye-catching, and the entire set has been quite affordably priced! Each headband is lightweight, adorably designed, and universally sized, and the elastic portions along the back feel reliable and secure. The decorative plastic buttons on each side can sustain some pull, so I believe that theyโ€™re there to optionally provide a resting place for the ear loops of face masks. Regardless, I think all of the patterns are vivid and cute, so Iโ€™d gladly recommend these boho hair accessories to others!',\n", + " 'This foaming cleanser genuinely provides an oil-free approach to daily acne control. I like that it contains botanical extracts, and it seems to provide a gentle, yet thorough, clean! Itโ€™s nicely packaged, affordably priced, has a pleasant scent, a 2+ year shelf life, and it always leaves my skin feeling nourished, soft, and smooth. Iโ€™d recommend it to others without hesitation!',\n", + " 'I can honestly say that this was the first time Iโ€™ve ever applied a sheet mask to my behind, but Iโ€™m always up for testing out new and inventive skincare items! Each product pouch contains plenty of hydrating essence, and each of the two included sheet masks folds out to make a quarter moon shape. It is definitely a bit challenging to try and place them by yourself, since it requires trying to twist your body around to see a mirror, but theyโ€™d be super easy to โ€œseatโ€ properly if you had an extra hand.

I will say that they do cling fairly well, and the essence feels nourishing, but the sheets ripple quickly with minor motions or movement. If youโ€™re standing when you place them and then lie down on your stomach, they shift around and lose some of their clinging magnetism, causing little ridges and ripples in the cloth that are no longer in firm contact with the skin. Upon removal, the remaining liquid essence does easily absorb, so I didnโ€™t experience any post-use stickiness or unpleasant residue, but Iโ€™m not entirely convinced the panthenol is a wonder ingredient.

Iโ€™m sure the amino acid solution does firm, tone, and moisturize the skin to a certain degree, but itโ€™s hard to really ascertain that after just one application, and since each pouch contains just one pair of treatment sheets, more of them would be required to determine if any noticeable benefits accumulated over time. Overall, I think this is an intriguing novelty item that many consumers might find humorous, so for that reason alone, I think itโ€™s worth giving these a try!',\n", + " 'This hand soap provides an effective and hygienic sense of all-natural clean! While I donโ€™t readily detect a heady scent of lavender oil, I will say that an earthy tea tree scent is freshly omnipresent. I love that this is a vegan, cruelty-free product thatโ€™s been consciously sourced, packaged, and produced, and the included pump dispenser seems to be quite sturdy and reliable. I appreciate that the bottle arrived with a secure safety seal in place, and I definitely didnโ€™t have any product leak out during shipment. Thereโ€™s also an expiration date handily provided on the bottleโ€™s base.

This slippery, soapy gel solution creates a visible sudsing effect, and it feels quite hydrating overall! It rinses away cleanly and leaves my familyโ€™s hands feeling nice and soft every time. I love using essential oils to help provide a renewed sense of revitalization and freshness around my home, so Iโ€™m gladly adding this Canadian hand wash to my daily cleansing arsenal.',\n", + " 'This is the first time Iโ€™ve ever used a stainless steel version of a gua sha scraper tool, but Iโ€™ve been decidedly pleased with the overall results! I love the super slick, shiny surface of this heart-shaped piece, and itโ€™s always cool to the touch at room temperature. Itโ€™s comfortable to hold, has a very slim profile, and it always immediately provides a relaxing sense of rebalanced alignment. This gua sha tool also comes with a pink polishing cloth and a red leather storage pouch! The snap is secure and reliable, the stitching is straight, and the scraper device fits snugly inside. Iโ€™m really pleased with this product overall!',\n", + " 'These do make affordably unique party favor gifts! The holographic print diamond ring designs are pretty, and I think the featured wording is memorable and cute! I will say that these hair coils are slightly larger than several others Iโ€™ve tried, so they donโ€™t seem to be as tight and stretchy as the ones Iโ€™m generally used to, but they do make a nice โ€œringโ€ design for the card, and the iridescent shade of purple is really attractive. Since they all come squashed together in a plastic bag with a slide zipper, they do move around and bend a lot. Because of that, 3 of the 7 decorative backing cards I received had obvious crinkles and bends across one bottom corner. They did flatten back out for the most part, but I still wish Iโ€™d received an entire set of pristine cards that were undamaged. Theyโ€™d make great gifts for bachelorette parties or bridal shower events!',\n", + " 'This ivory-colored bath mitt comes packaged in a resealable pink pouch, and itโ€™s super lightweight! The packaging says it is 100% natural silk, but it does look and feel more like a linen/cotton fabric. Regardless, itโ€™s soft enough to be gentle, but just textured enough to provide some noticeable friction for exfoliation! It fits comfortably over my hand, and itโ€™s simple enough to grip and hold and air dry after each use. It can be used alone with warm water, but Iโ€™ve used it in combination with several body scrubs and it further works to enhance the gritty benefits of all of my exfoliating sugar and salt concoctions. Iโ€™d recommend this natural glove for all skin types, and it can be used in conjunction with bath OR shower time. Iโ€™d realistically pay $12-$15 for it, but Iโ€™m pleased with its overall performance!',\n", + " 'Vitamin C is definitely an essential component of a healthy body and skincare routine, and I love that this smooth cream also contains shea butter, vitamin E oil, rosemary, jojoba oil, aloe vera, cocoa butter, and lavender essential oil. This lotion has a pleasant scent, and it seems to work great with overnight applications. It leaves my skin feeling hydrated and moisturized the next morning, and it has even helped diminish the appearance of minor blemishes over time. I love that this product is USDA-certified organic and that itโ€™s made in small batches in the USA! The tub comes adequately sealed with a clearly marked expiration date, and I think itโ€™s affordably priced for the results it provides. ๐ŸŒค',\n", + " 'I love this skincare set! The pale pink rose quartz hue is such a pretty shade, and the paired duo arrives safely nestled within a cushioned pillow of foam cutouts. The dual-ended roller exhibits smooth and silent movement, and the gua sha stone is perfectly sized and comfortable to hold! The warm gold metal hardware pieces complement the pink color beautifully, and the overall craftsmanship of this set is impressive. This product would make a chic and affordable gift for yourself or a loved one!',\n", + " 'The blend of royal jelly, botanical, and floral extracts gives this Korean beauty essence a nice ingredient profile, and the overall scent is pleasingly fresh and sweet. Each of the pouches has a small twist-off cap and the liquid contents are clear (and seem to have a high water content). The spread solution initially dries a little stickier than Iโ€™d prefer it to (stickier than a well-absorbed moisturizing lotion would), but the eventual result feels hydrating overall. Due to the compact size and flattened shape, these pouches would be great for travel. Especially after a day at the beach!',\n", + " \"These nipple covers aren't perfect in every way, but they do offer some reassuring coverage! I do like that they come in 2 different shapes, and I like that theyโ€™re super lightweight and easily portable. The satin coverings are soft and smooth, and the light beige hue is an acceptable shade that would complement several skin tones. I will say that the paper backings donโ€™t peel off smoothly every time, and the fabric has a slight tendency to wrinkle and ripple, so the covers donโ€™t stay completely flat throughout the entire duration of wear. The rippled texture is still somewhat visible under t-shirts, the edges are slightly detectable, and I think Iโ€™d have to layer two of them together to really ensure full coverage. Iโ€™ve had no adverse reactions to the adhesive component, they peel off easily, and I even wore a pair while sweating in the summer heat in Texas, and they stayed firmly in place.\",\n", + " 'This boxed set of smooth, golden eye mask pairs is totally fabulous! Each pair comes individually packaged, making this collected group of beauty accessories excellent swag-bag additions or party favor gifts! The included serum feels incredibly hydrating and smells absolutely divine. Iโ€™ve used several different brands of similar eye masks, and these are noticeably thicker and more substantial than every other pair Iโ€™ve tried! Even at room temperature, they instantly provide a cooling sensation when applied to the face. They adhere well to skin, but due to their weight and size, they do have a slight tendency to slip downward with gravity. For that reason, I suggest lying flat or reclining while wearing them, so that they stay as close to the lower lash line as possible. Each package still contains some extra serum after the eye masks are removed, so I massage that residual liquid onto my neck for added moisture potential. The combination of hyaluronic acid, collagen, and 24k nanogold particles leaves my under eye area feeling incredibly hydrated and refreshed. Consistent use of this product helps combat fine lines, puffiness, and dark circles over time, so Iโ€™m thrilled the whole set is so affordable! I couldnโ€™t be more pleased with this product.',\n", + " 'This face wash provides an invigorating sense of clean with a burst of fresh citrus zing! I love that it contains aloe vera, vitamin C, rose hip oil, and lemon and orange peels! ๐Ÿ‹ It goes on smoothly, rinses off easily, and seems to have an ideal consistency. I have gladly added this vegan product to my daily skincare regimen, and Iโ€™d order it again without hesitation. It provides smoothing, hydrating, radiant results and it smells incredibly delightful!',\n", + " 'This is a beautiful and affordably priced facial set! The Brazilian rose quartz stones are a pale shade of pearlescent pink, and the rose gold hardware is the perfect complement to them! The rollers move silently, as promised, and they donโ€™t seem to rust or wear out in any way. The stones are cool to the touch at room temperature, but placing them in the refrigerator (before use) ensures an ultra-chilled experience. I love that the magnetic box lid has instructions printed on the underneath side, and the soft, drawstring pouch is an added bonus! The set even comes with a informational mineral card that provides reassuring details about the quartz pieces featured. Each tool is perfectly nestled within in its own compartmentalized cutout, and the rollers definitely seem to help increase circulation and boost overall skin radiance! This would definitely make a perfect gift set for someone!',\n", + " \"I have thick, wavy hair and need a thick brush. Over a decade ago I discovered that boar bristles work best, but finding one I can take with me was a process. I didn't like those with exposed bristles, so there weren't many options. This is the first folding boar-bristle brush I found.

The plastic is light and gives the impression that it isn't of the best quality, but it's survived my backpack just fine. This is a portable brush, so using it requires more strokes through my hair, but that's a price I'm not hesitant to pay. It's come in handy for my kids too, who also have the same hair-and-brush combination.\",\n", + " 'Love it',\n", + " 'This is an amazing contour pallette',\n", + " 'Works great',\n", + " \"I've been using this product for over 10 years. Never disappoints.\",\n", + " 'This is a very large and heavy dryer. I am keeping it as I need one right now but would not buy it again. Hard to handle. Certainly too large to travel with.',\n", + " 'My favorite facial wash!',\n", + " 'These are just the right size, and do the job.',\n", + " \"This's a great product especially if you're lazy like me.\",\n", + " 'eco friendly and very soft',\n", + " 'good length thick enough to not snap off',\n", + " 'pompoms are a lil small headband is comfortable',\n", + " \"Got this bag to wash the dogs feet in when they come in from outside.
So tired of trying to wash them and I've tried the small bucket thing to dip their feet but they don't work cuz their feet are so big, lol.
This bag I just fill up and have them walk right in and I clean them up, works great! No water leaks!\",\n", + " \"This nail lamp was bought for myself and the girls when we meet up for beauty time!
We keep fighting over who is going to use the lamp next so we decided to get a few of them Lol.

Now this one in particular I enjoy using because it dries fast plus I don't feel the heat so much like other lamps. Definitely a good one in my book!\",\n", + " \"This kit comes with everything you need to take off nail polish.
This particular set was for my mother in law who is just getting into gel polishes and she didn't understand what the clips were for at first ๐Ÿคฃ
After I showed her how it took off the polish with scrubbing she was SOOOOO glad I got her this set!\",\n", + " 'Never tried poly gel before, definitely not easy but worth it! Check out my nails in the photo, came out beautifully and they are very strong!',\n", + " \"I've had an obsession with gels with my time off from work these past months and I wanted to try this color changing polish.
It comes with designs and while the color itself is dark it does change.
I am enjoying trying the designs but man it does take practice!!!\",\n", + " \"Great for your pores and acne. My husband's back started breaking out and after using this for a few days it's clearing up and looks less irritated. Plus it came with a bag which I didn't know what for until I read the instructions and it is a foaming bag and it really makes the soap foam!\",\n", + " \"Made my hair soft again! Not the easiest thing to get on when you have long hair but I managed. Then after the time required I wash my hair and couldn't believe how soft it was. It hasn't been that soft in a long time. So I definitely think it was worth the trouble stuffing all my hair in there and letting it sit plus it doesn't smell the greatest, nor does it smell bad I'm just used to very perfumed shampoos. But I'll definitely be using it again.\",\n", + " 'I am so glad they made a product like this because I can never seem to find the right color to match my skin and I end up with that Foundation the line on my chin with the two different colors. Not only is this product lightweight, it smells nice, plus it blends in with my skin tone almost perfectly. This is definitely going to be my go to Foundation.',\n", + " 'Exactly what I was looking for. Thank you.',\n", + " \"This is the best thing ever!!!!! I have pain 24/7 and this is awesome!!! I rub this on and the warmth is felt right away! Better than the prescription creams they've given me! I can't sleep without it!!!!\",\n", + " 'Work great. Fair price.',\n", + " 'So far this seems to be a good product. It definitely helps rid me of acne scar when used within a combination of other products.',\n", + " 'My daughter loves the foot pedicure unit.',\n", + " 'well, I love the picture!!!!!!!! granddaughters absconded with them and are very reluctant to share. I will be buying some more so I can actually hold my hair back.',\n", + " \"safe step up to whatever you can't reach. i use it to get into the tub easier. it is quality built and does the job.\",\n", + " 'I got these because I have tiny wrists and the originals were annoying when I was typing and didnโ€™t have my hair up. They work just as well and are half the thickness.',\n", + " 'Great amount of products for the price. A lot of sample sizes but the value on some of the products is insane. Loved trying so many things that I wouldnโ€™t consider normally.',\n", + " 'Honest and True: My husband enjoys keeping is travel items organized and itโ€™s helps me to keep him properly packed. Great travel bag.',\n", + " \"Despite having a thick-ish, creamy consistency, the conditioner not only dispenses without issue, its also easy to work into/rinse from hair. Does a nice job of protecting color while detangling and softening. However, I don't really notice any added shine or volume.

I'm beyond thrilled to say it has the unique Moroccanoil product scent that not only smells lovely but actually lasts for a decent amount of time; a rarity with my hair!

I love Moroccanoil products and while I do like this, its not my favorite in the line. I have no plans to purchase this in the future, I'll stick with their hydrating conditioner.

Overall score is 3.5 stars\",\n", + " \"This is a very reasonably priced exfoliator that does a great job of exfoliating and cleansing as well as hydrating and smoothing. Its packed with antioxidants that are excellent for good skin health. The instructions says to use 2-4 times a week. I use it twice a week and follow with a good facial moisturizer. I can't say that I experienced a change in my aging skin but I also haven't been using it very long. There is a nice scent that is pretty much gone once the product has been rinsed off.

I have dry, sensitive skin and have no issues using this.\",\n", + " 'This is an ideal moisturizer for my dry, sensitive, aging skin. It applies easily and absorption is fast. Does a nice job of calming the patches of eczema while moisturizing and firming. I like the ingredients, especially the cactus oil. There is a scent; its a nice scent but it fades quickly. The price is on the high side but worth it.',\n", + " \"This is a nice, light gel cream packed with aloe and hyaluronic acid, 2 things I love to use on my dry, sensitive aging skin. Easy to apply-a little goes a long way. Absorption is fast and does not leave a greasy/stick feel behind. Instantly hydrates and soothes the red patches of inflammation that plagues my skin.

The cream itself if a light blue-ish/grey-ish color but don't worry, it doesn't discolor skin. There is a bit of a scent that I find to be medicinal though it fades quickly.

I do not know if it occurred during shipping (the product shifted) or if its normal but my jar seemed to be missing some cream (see photo). Despite this, its still a good, affordable cream that works well on even the driest of skin.\",\n", + " \"While XXI Bio-Pure facial moisturizer is packed with great skin care ingredients such as jojoba, shea butter, aloe vera, sunflower seed oil and glycerin, I think its the Vitamin C that really makes this an exceptional product. At least for my skin it's exceptional.

This is a nice, lightweight moisturizer that absorbs quickly and doesn't cause skin to look/feel oily or greasy. It softens and smooths skin. Fine lines are thinned. My dry, sensitive skin looks and feels refreshed. And thanks to Vitamin C, my normally dull skin has a dewy glow. I've not found many products that are able to do this to my skin but XXI does!

I have dry , sensitive skin and have no issues with this cream

XXI works. It works VERY well and some results like soft, smooth skin occur immediately after use. Results are long lasting. XXI recommends using this in the morning and at night. I use it once a day in the morning. A very small amount is sufficient to cover my face. Because it works so well and delivers great results and only a small amount is needed per use, I do believe the price is reasonable. However, if you find this isn't right for you, XXI offers a 30 day satisfaction guarantee. I absolutely recommend XXI Bio-Pure lotion.\",\n", + " '\"Best shave I\\'ve ever had. Gives me a close shave with no tugging. Better than an electric razor\".

That\\'s the first thing my husband had to say after he tested SUPRENT\\'s Matrix Cutter Head travel kit razor for the first time. And what a kit this is. A razor handle, 2-blade refills (each with the first of its kind 6 ultra-thin blades total!), a dock to hold the razor and a bottle of shaving foam are included.

The handle is sleek and heavy but easy and comfortable to hold. The head doesn\\'t pivot but it doesn\\'t need to thanks to the 38.5 degree shaving angle. It glides perfectly along the jaw line and chin areas without missing a spot.

The base is heavy-ish and holds the razor well. Doesn\\'t tip or wobble.

He\\'s not a fan of the shaving foam. Says he must \\'really rub it in\\' in order for it to foam. He used it once and switched back to his regular brand.

Suprent has really come out with an awesome razor kit. The presentation is gorgeous and the product works exceptionally well. Without a doubt this is worthy of gift giving. The price is reasonable.

Highly recommended',\n", + " \"I love how easily and quickly Tinazana's Pineapple Deep Cleanser becomes a creamy lather that feels really nice on my face. A very small amount of the cleanser does a great job of deeply cleaning pores and removing dead skin cells. My face feels fresh and clean after cleansing. But it does dry out my skin a bit. Because I follow up using toner and moisturizer, this isn't a huge deal for me and doesn't prevent me from continuing to use Tinazana cleanser. There is a light, faint, fresh scent that I enjoy. Surprisingly, it doesn't smell like pineapple to me. It also doesn't last; when I rinse the cleanser off, I can no longer detect the scent at all.

Due to skin sensitivity issues, I sometimes have issues with citrus based products. I know pineapple technically isn't a citrus fruit but I was a bit concerned it might be too harsh on my skin. Its not. No burning or itching at all.

I like this cleanser a lot. Does a great job, even with drying my skin a bit. The price is reasonable. This is a cleanser I will continue to use and I recommend it.

My overall rating is 4.5 stars.\",\n", + " \"I LOVE Hask hair products. I'm a huge fan and have been for some time. So, I was super excited test Hask's body wash. But I had a problem right from the start. I had to decide between 4 fantastic choices! Coconut, Lavender + Vanilla, Cucumber + Aloe and Shea + Cocoa Butter. Since it was very warm outside the day I ordered and with summer rapidly approaching, I chose Cucumber + Aloe.

Perfect choice!

This is a 2 pack of 24.5oz Hask Cucumber + Aloe Body wash. The scent is delicious- light , crisp and not at all overwhelming. The bottle's pump dispenses easily as well as a good amount of body wash. It lathers quickly and does a great job of cleansing skin. I also use it while shaving my legs and it works well. When I step out of the bathtub my skin feels wonderful and I feel nice and relaxed. The aloe helps hydrate and moisturize my dry, sensitive skin.

The 2 bottles are big in size and will last for quite some time in our home. That, along with the great results make the price reasonable. Recommended!\",\n", + " \"John Frieda's Detox shampoo/conditioner duo is an excellent way to revive and restore hair. The shampoo does a brilliant job of not only cleansing hair, it cleanses the scalp and washes away buildup leaving hair soft and shiny. The conditioner detangles, hydrates and adds bounce to even the driest hair.

Both have a nice scent though it doesn't last long, at least not in my hair! Each is easy to work into hair and rinse out as well. I like to use this duo once a week. I experience no color fading or allergic reactions as I have sensitive skin. Definitely worth the price and absolutely recommended!\",\n", + " \"I'm so amazed by boar bristle hairbrushes and how incredible they make hair look and feel. This GAINWELL boar bristle brush is a wonderful, compact brush. It may be small but it works wonders on our family's hair. It works through tangles without pulling or causing pain while leaving hair soft, shiny and manageable. The compact size makes it perfect for travel, to keep in a purse, a school/gym locker, briefcase or even a pocket. If you've never experienced a boar bristle brush, I HIGHLY recommend giving it a try. You can't be the price and the results will be worth it! If, for some reason you're not satisfied, GAINWELL asks you to contact them for assistance. I can't imagine they receive a ton of calls with issues but its great to know customer service is a priority!\",\n", + " \"Thanks to dry, sensitive skin, I'm always a bit concerned when trying new skin care products. With regards to masks, I've tried some that have worked well, some that caused my skin to burn and some that caused my already dry skin to become even drier. It makes me SO happy to report that I do not experience any negative issues with HUXLEY Secret of the Sahara Clay mask. I would have been crushed if I had experienced a negative reaction because this really is one heck of a clay mask!

Huxley is a nice, gentle mask. But don't let that fool you, it may be gentle but it does a heck of an exceptional job! It applies nice and easy. I let it sit on my skin for 10 minutes before rinsing with lukewarm water, right before its nearly dry. It exfoliates well leaving my skin soft, smooth , a bit brighter and healthy. Dead skin cells are washed away. My skin literally feels GOOD after using Huxley. This mask does have a light scent but it doesn't last long. It is recommended Huxley be used 1-3 times a week. I use it twice a week though I could probably get away with using it only a week because the results Huxley delivers are long lasting.

I'm so relieved I will be able to continue to use this mask on my skin. Silly as it may sound I kind of feel like I'm pampering myself when I use it-it makes my skin feel that GOOD! I will continue to use/purchase Huxley, I'm that satisfied/impressed with what it does for my skin. I absolutely recommend Huxley.\",\n", + " \"I take Melatonin to help me sleep just about every night. I had NO CLUE melatonin helps improve skin condition as well! I have very positive results when I take it to help me sleep. I'm guessing it plays a role in why I experience great results with MU TENUTO Bereceuse Water Gel cream as well! I love the consistency of this cream. Its a nice, light gel. It doesn't take much cream at all to cover my face. It applies/spreads so easily on skin. The first time I used it, I was concerned that it was going to be sticky. Fortunately, that's not the case. It absorbs quickly leaving my skin soft and smooth immediately. I can not only see it but I can feel how it hydrates my skin as well. My skin is normally extremely sensitive and very dry. The hydration really makes my skin feel great. I apply the cream at night before bed and enjoy the results in the morning when I awaken. Lavender is one of my favorite scents. But I just do not care much for the scent of this cream. I will not deduct a star from my rating due to the scent...the scent doesn't last long at all. I don't think its fair to penalize the cream for a scent that doesn't last long. I have no negative reactions to MU TENUTO. It works and feels great on my sensitive skin. For those interested in packaging, the jar is glass-nice and heavy with music notes all around it. And here's a neat feature...if you scan the QR code on the package, a snippet of classic music will play on your Smart phone! That's pretty neat.

I love what MU TENUTO does for my skin and works with the very first use! I find the price reasonable. This is an excellent cream-it takes wonderful care of my dry, sensitive skin. Definitely recommended!\",\n", + " \"EXURE is a pretty impressive leave-in conditioner that does a great job of softening and smoothing my hair. Its packed with an impressive array of nutrients, amino acids, vitamins, antioxidants that protect and heal damaged hair while also adding shine. I don't need to use very much on my shoulder length hair. EXURE has a fabulous scent as well. I don't have any issues with EXURE weighing my hair down or making it look/feel oily or greasy.\",\n", + " \"Should I start my review by telling you how incredibly creamy Easydew Daily face wash is? How it makes my skin feel great as I'm washing with Easydew and even better after I've rinsed it off? How much I love the scent?

Don't worry, I'll tell you everything! This is my first ever Easydew product. In fact, prior to seeing this face wash in my VINE offers, I'd never even heard of Easydew brand products. I'm so happy I ordered it.

A nice, thin line of the wash dispenses from the tube. (The tube is very sturdy and durable, for those interested in packaging) Now, the wash starts out like a kind of lotion but it lathers quickly and easily into a light, whipped foam. ( A dime size amount is all I need to sufficiently cover my face/forehead. ) The whipped foam is SO creamy and it just feels so darn good as I apply it and when its on my face. IDK if its possible but I swear I can feel it cleaning, hydrating and moisturizing my skin pretty much immediately. After I rinse with lukewarm water and pat my skin dry with a towel, my skin is soft, smooth, clean and has a bit of a glow. It looks and feels so good and healthy. It feels fresh. And it feels that way long after I've used Easydew. Easydew leaves my skin feeling like it did when I was younger-before I used makeup, before I spent too much time in the sun unprotected. It feels revived and I just love that feeling! Everything about this daily wash is perfect in my book. It works great and makes my skin look/feel great. The ingredients and what they do for skin is impressive. (I recommend taking a minute to read the info above regarding the ingredients!) The scent is wonderful (though it vanishes VERY quickly). And I have no issues using it on my dry, very sensitive skin. The price is more than reasonable, especially with the results the wash brings and the fact only a small amount is needed when I wash my face. Easydew is officially a part of my daily skin care routine now. I absolutely recommend Easydew!\",\n", + " \"I am finding SO many uses for Shiny Leaf's coconut and sweet almond oil! I do have some experience with coconut oil but this is my first time using sweet almond oil. Thanks the labels on the bottles, reviews and internet searches, I'm finding SO many ways to use these oils...sometimes together, sometimes individually.

Because I have terribly dry, sensitive skin, my main goal was to see how one or both oils could help protect my skin, especially now that winter has arrived and my skin is REALLY taking a beating. Both oils work well to hydrate and moisturize, so I mixed a few ounces of each in a mist bottle. After I bathe, I mist a combo of the oils over my skin to help hydrate and moisturize. The oils absorb quickly and do not leave an oily/greasy look OR feel to my skin. I'm already seeing a decrease in my dry skin/itchy red patches of skin. I experience NO discomfort whatsoever when misting these oils onto my sensitive skin. Both oils also work wonders on hair by moisturizing, hydrating, improving hair texture/strength, stimulate hair growth /thicken hair, and nourish the scalp to prevent dry, itchy flakes. In addition to using my combo of oils after bathing, I also give my hair a spray or two with the mister and sure enough, I'm seeing less hair in the drain and on my hairbrush after brushing. My hair is soft, smooth and shiny WITHOUT looking or feeling oily/greasy from the oil combo.

I use the coconut oil (alone) to help remove makeup, under and around my eyes to soften and reduce fine lines, I rub a small amount into my scalp (as does my husband) to help stimulate hair growth, on the kid's faces after their baths to soften (especially in cold weather!), on my nail beds every couple of days and a light amount on any patches of eczema/red skin. (It relieves the itching/burning and redness from eczema quickly!)

I use the sweet almond oil (alone) on dark circles under my eyes, a SMALL amount on split ends in my hair, a drop on chapped lips, I'm just starting to tinker with it for aromatherapy purposes. I recently learned that it can help fade scars so I've begun to rub some sweet almond oil into a scar on my finger to see what happens. If it helps, I'll then move on to a small facial scar I have. I'm also trying something on my own; just started doing this a few days ago. I get nosebleeds every single day, at least once a day, throughout the winter when the heat is on in the house. This started when I was 2 years old, I'm now 49 so I've experienced this my entire life. I now rub a small amount of sweet almond oil under my nostrils before bed. Since starting this, I continue to have nosebleeds. Yesterday, I had only one and it involved just a few drops of blood. I didn't whip through numerous tissues like normal. ONE tissue took care of it. (that's huge for me!) I have NO clue if its just a coincidence or if the sweet almond oil is helping in any way but I'm going to continue using it.

These oils are phenomenal! Both bottles are 16oz. I love the fact that they have normal caps on them but pumps for each bottle are included as well. The liquid of each is thinner oil than I expected, which I prefer. Both absorb quickly. Neither has a scent. I've found SO many uses for these oils, I can't wait to discover more. ( I'm SO happy with these oils, I recently purchased Shiny Leaf's biotin hair conditioner and cannot wait to try it! ) I find the price to be incredibly reasonable, especially since you're getting TWO bottles of oils! HIGHLY recommended!

*FYI...the mist bottle on the end in my photo is NOT included! I used one of my own mist bottles to combine both oils. You will get both bottles AND pumps that you see in my photo, NOT the mist sprayer!\",\n", + " \"The directions on the tube of FRESHME's mud mask (pelargonium graveolens) state those with sensitive skin should use the mud mask once a week. Because I have sensitive skin that's precisely what I did. I also followed the directions that state the mask should be used after bathing or after warming the skin with a towel for 5 minutes. Perhaps my skin is just too sensitive because I really didn't notice much of a difference after using this mud mask. Its on the light, watery side so its easy to apply and doesn't take much to cover my face. In the 15 minutes it sits on my skin (10-15 recommended per directions) it never entirely dries and I don't experience the feeling of skin tightening at all. After I rinse it off (it rinses without issue), my skin feels clean but a bit dry. I cannot detect any change to my pores. This just isn't the mud mask for me. I've discontinued using it and will be giving the rest to my niece over the holidays. My review will be updated if she has better results than I.

--photo #1-taken right after I put some mask on my hand
--photo#2-taken after mask sat on my hand for 15 minutes (doesn't dry entirely)\",\n", + " \"Somehow, I managed to dodge dark circles under my eyes for most of my life...until a few years ago. Now, they're the 'norm' for me. Same for puffy eyes. FRLEDM's 24K gold under eyes patches help tackle both issues and do so quickly. I keep the patches in the fridge-I get better results when they're cold and it feels good as well. I wear the patches in the morning for about 15 minutes and I'm good to go. It did take multiple uses before the results were obvious but that's to be expected. I like many of the ingredients in the patches, including: collagen, hyaluronic acid (HUGE fan!), and aloe, to name a few. I'm not a fan of the roller, unfortunately. I just do not care for the way it feels on skin...its not smooth and gentle, more like tugging and pulling. I will be passing it along to my mom who is anxious to try it.

While I'm not a fan of the roller, I am a fan of the patches and am pleased with the results they provide. I will continue to use the patches and definitely recommend them. I hate to say that I don't recommend the roller just because I don't like the way it feels so I will just say its not for me.\",\n", + " \"My husband has dry skin that is worsening now that cold weather has arrived and the heat is on in the house on pretty much a regular basis. I ordered this cream to help moisturize his dry skin as well as reduce his fine lines as he approaches the 'big 5-0'. He's not yet noticed a reduction to his fine lines though he hasn't been using the lotion very long but he is pleased with the job its doing to help moisturize his skin. His skin isn't nearly as dry as it had been so he is experiencing some much needed relief. He is a fan of the scent and he's happy that the lotion doesn't cause his skin to look or feel oily/greasy. He's definitely satisfied with this cream and the results he is receiving thus far.\",\n", + " \"I ordered LA LA Leaf Guayaquil hemp lotion for my husband . While it is indeed a hands and body lotion, it targets especially dry skin areas-elbows, feet and heels. He has unbelievably dry , rough elbows and does so year round. He's always rubbing creams and lotions into his elbows with very little positive results. Until now. LA LA Leaf is softening his terribly dry, cracked elbows and doing so each time he applies it. He has pretty much stopped complaining about his dry elbows, instead expressing (nearly EVERY. SINGLE. DAY!) his excitement now that he has finally found a remedy. lol. While I ordered LA LA Leaf for him, I've now started to use it on my hands as well. Its lightweight, absorbs quickly and doesn't cause my skin to look or feel oily or greasy. Let me tell you, the hemp oil, rose flower water white bark extract , aloe (a fave of mine) ingredients do a heck of a job softening and smoothing my hands after I apply LA LA Leaf. I'm already planning on using extra LA LA Leaf in the winter when my hands get the dreaded deep, extremely painful cracks due to cold weather. I noticed in the info provided above, this lotion can be used after spending time in the sun. Because my skin is so terribly sensitive and dry, I do believe I will use LA LA Leaf after spending time outside in the sun when the weather gets warmer. Regardless of where you use LA LA Leaf on your body, its going to leave you with soft, smooth skin and will do so quickly. I do believe LA LA Leaf is worth the cost. It doesn't take much lotion to cover the skin (in the areas we are using it on) so this tube is going to last us a decent amount of time. I have every intention of continuing to use/buy LA LA Leaf. It's wonderful\",\n", + " 'If you\\'re a dog owner, its practically guaranteed at some point, you will have to deal with your dog having dirty, muddy paws. Happens often with our bichon Mac. (Naturally, it recently happened right after I cleaned and mopped the house! lol) I ordered the Mr. Ros automatic cleaner for small/medium dogs. Its very sturdy and durable, not at all flimsy. Its roughly 8\"tall and has a removable mat with silicone bristles in the interior which is easily removable for cleaning purposes. The bristles are very soft and not at all hard or sharp. It arrived already charged. A USB cord is included. To operate, simply add water to the washer-(2-3 cups per instructions) Liquid soap may be added as well. (I didn\\'t use soap) Turn the washer on-it does make noise though its not terribly loud at all-and place the dog\\'s paw in the washer for 1-2 minutes. Dry each paw with a towel after cleaning. Mac wasn\\'t thrilled throughout the cleaning process but he also wasn\\'t really scared by it. My husband started to pour out the dirty water before I could stop him so you won\\'t see much, but you can see in my photo the water is discolored a bit following the cleaning. If a wet towel isn\\'t enough to clean Mac\\'s muddy/dirty paws, my regular cleaning method is to put some lukewarm water in a small bowl , dunk each paw one at a time and use my hand to remove the dirt from his fur while submerged. Quite honestly, I really don\\'t see much of a difference between that cleaning method and the Dr. Ros paw washer. Perhaps results vary depending on the breed of dog but for our bichon, I really don\\'t see a difference.',\n", + " \"You know the saying 'kill two birds with one stone'? That is precisely what I had in mind when I ordered Follain Mattifying Moisturizer. I have dry, sensitive skin but its not oily. My husband has oily skin. I have fine lines and wrinkles on my face. My husband does not. Because Follain moisturizer promises to combat oily skin, as well as fine lines and wrinkles and is a clean, vegan product, I ordered it to find out if it could help the both of us with our skin issues. I'm happy to tell you that it has helped the both of us. The moisturizer is a bit thinner than I'm used to. I don't say that in a bad way because its not at all bad. One pump of the canister delivers enough moisturizer to cover my facial skin. Its very lightweight and absorbs quickly without leaving a look or feel of oily/greasy skin. It provides immediate hydration and does a nice job of softening my skin. I am VERY happy to say I absolutely have a noticeable reduction in the fine lines and wrinkles on my face. They don't go away entirely, but there is a definite reduction in size and appearance. ( I can't tell you how much I needed to experience this right now as my 49th bday is this week...that means 5-0 isn't far behind and I'm kind of starting to freak about it! ) My husband also tried this for his oily skin with impressive results. Follain controls his oily skin and prevents the shiny, damp look that comes with oily skin thanks to the mattifying benefit of this moisturizer. We both use it as needed and not even on a daily basis. Follain works and it works well. We're both very pleased and grateful for the results!\",\n", + " \"Boy oh boy, does my dry, sensitive skin LOVE LOVE LOVE Higher Education's Goal Digger cucumber creme! This is a wonderful lightweight creme packed with important nutrients such as: cucumber extract, kale, melon, cabbage, ginger and turmeric, to name a few. Together, these ingredients hydrate and soften skin and do so quickly. The creme applies nicely -a little goes a LONG way. My skin absorbs it very rapidly and it does not leave a greasy/oily feeling. It has a nice, light, refreshing cucumber scent. This creme will not make your wrinkles and fine lines vanish entirely but will help visibly reduce them. If you have dry, sensitive skin you're going to want to try this creme. It will do wonders for your skin!\",\n", + " \"My feet are so horribly dry and cracked, they look like funky fish scales. I was anxious to see if Monikahair's foot peel mask could help. The process is incredibly easy and requires next to no work. Prior to starting, I cleaned my feet. ( The lotion for the treatment is already in the socks). I then placed a plastic 'sock' over each foot and used the tape on each sock to seal them closed. The instructions say to keep the socks on for 60-90 minutes but I got wrapped up in an episode of 90 Day Fiance and kept them on for 2 hours. lol. The lotion did not cause any issues for me...I have extremely sensitive skin and had no reaction of any kind to the lotion. It did not cause burning/itching, etc. When the time was up, I removed the socks and cleaned my feet.

Here's what happened:

Day 1 (the day after I did the treatment)-nothing

Day 2-VERY light peeling-more like little 'threads' of skin

Day 3-Actual peeling -I was pulling some decent pieces of skin off of both feet

Day 4-WOW...BIG pieces of peeling skin! (unfortunately, I had already started to peel off the skin when I remembered to take a picture for this review...the picture does not show just how much peeling had actually taken place)

Day 5-Very little peeling-mainly on toes

Day 6-Next to no peeling

Day 7 & 8-No peeling at all

Results:

The bottom of my feet are soft and pink with the exception of my heels. Those are my trouble areas. Calluses are very thick and cracked on my heels. (a million times worse during winter months!) I DID have some progress on my heels but nowhere near the rest of my feet. I used the scraper (? not sure if that's what it's called) and made a bit of progress. I wish now that i had wiped some of the lotion directly on my heels when I wore the socks. When I do my next treatment, I will absolutely rub some lotion directly on my heels when I start. I'm impressed and thrilled with the results. Its flip flop season and my feet aren't always pretty to look at. This foot peel really helped. I absolutely recommend Monikahair foot peel if your feet are dry and cracked. They're going to look and feel SO much better after using this treatment! (I told my mom about my success and she already ordered one of herself !lol )

Photos:

#1-wearing the 'socks', #2- day 2, #3-day 4, #4-finished

Day 5\",\n", + " 'A few weeks ago, I tried a different brand of purple conditioner. This was the first time I\\'d ever used any purple conditioner on my blond hair. After using the other brand, I noticed a subtle change to the brassiness in my hair. While I was satisfied with the results, I also assumed it had done all it could do for my hair. Tonight, I tried WELLUTION Purple Hair Mask (for blonds). The mask is easy to apply and it distributes nice and even on my hair. My hair is thick and shoulder length. It didn\\'t take much mask to cover all of my hair. ( I did put extra mask on my roots/scalp area because I do dye my roots) I let the mask sit on my hair for 10 minutes. It has a nice scent to it that I very much like. I had no issues rinsing the mask from my hair. It rinsed out without issue. It did not cause my hair to look/feel oily or greasy. I was able to comb it without issue and let it air dry. When my hair was completely dry it looked and felt nice and soft. My natural waves were present without flyaways. But...I also noticed my hair was FAR less brassy than it had been. The change was not subtle the way it was with the first brand I\\'d tried weeks ago. This was very noticeable. To say that I\"m pleased with this mask is an understatement. Its wonderful. And I WILL continue to use it as needed. Blonds, if you\\'re dealing with brassy hair, give this mask a try. I hope it works for you as well as it did for me.',\n", + " 'Very โ€œrustyโ€ color.',\n", + " 'Of course, I love Trรฉstique, but I especially love this lip primer! Itโ€™s not chalky nor sticky, but provides a great priming for Trรฉstique lipsticks. I like the primer so much that I purchased them for all of my Trรฉstique lippies, as opposed to balm that comes with the glosses. It gives your lipstick longevity and allows for fullest pigment payoff!',\n", + " 'Simple, thoughtful design. Priced right. I use this to allow brushes to dry after washing. Works perfectly!',\n", + " 'I Love these hats for bedtime, Keeps my hair in place and looks cute. And stays on good. Thank YOU',\n", + " 'Try as I might, these clips simply would not stay in my thick hair. They kept slipping and falling out. They are weak and have no grip whatsoever. Others with thinner or finer hair may have better results.',\n", + " \"I have very thick hair and when these arrived I attempted to use it to finish a bun. Nope. Thick hair weighs a LOT and this bird nest hair clip just adds more weight and since my bun isn't on top of my head, the clip's weight pushes my bun off the back of my head. I had high hopes for these cute clips, but unfortunately they are a no go for me. I've donated them to my local women's shelter.\",\n", + " \"I got this KLAVUU Nourishing Care Lip Sleeping Pack and have been using it nightly for a few weeks now. I have found that it is tasteless, odorless and does give me very soft lips by the next morning. However, it is extremely thick and sticky and it doesn't absorb very well. I apply it right before bed and no matter how careful I am to apply a very small amount I always need to use a tissue to dab the excess off so my lips don't stick to my pillowcase and so lint isn't attracted to and stick to my lips while I sleep. So, even though I have soft lips in the A.M., this is a pass for me.\",\n", + " 'Easy to use, my face was noticeably tighter the next morning and the price is right on point for the pack of 10 that you get. Add to that the scent is not overpowering and there was more than enough serum to get the job done. Thumbs up!',\n", + " \"FINALLY!! Hair scrunchies that will not only hold my thick, medium length hair in a ponytail but will also STAY in my hair! I am so tired of scrunchies that fall out of my hair. Seriously. But I got these and they stay put! I am SO happy that I don't have to mess with a falling ponytail all the time anymore! The colors are very nice and the elastic is the best I've ever found in a scrunchie. I will be buying more in other colors!!\",\n", + " \"The cuticle oil is so very hydrating. My cuticles (both on my feet and hands) are always dry and cracked and this oil really helped them not only look better but feel so much better! I appreciated the easy roll-on applicator too. The body lotion is a decent lotion. I wouldn't say it is earth-shattering or mind-blowing.. but it does smell really good and the scent isn't too overwhelming or powerful. My grandma is sensitive to powerful scents and she didn't turn her nose up at it so there's that. It is a decent thickness (not too runny or too thick), it absorbed relatively quickly and it makes my skin feel soft. The packaging is over the top, in a bad way. As a eco-minded person, the amount of packaging used was just ridiculous and unnecessary, IMO. My experience doesn't justify the price.. for the amounts you get and the average results are not equal to the price paid. Overall, this is a nice set and gift-worthy, but I probably won't purchase it again.\",\n", + " \"I got this CURECODE serum in hopes of introducing more moisture to my dry face (gotta love winter). The very first thing I noticed was that, while there are directions on the box, there are NO instructions on the bottle itself. I'm not in the habit of keeping the packaging (who does that?!).. they need to add the directions onto the bottle label!

The serum itself is pleasing. There was NO scent (THANK YOU!), my sensitive skin had no negative reactions at all and I was pleased with the thickness. It didn't completely absorb into my skin.. I had a few pieces of pillow lint (flannel sheets) stuck to my cheeks the next morning. I can't say how well it works long term yet, but I have high hopes as my skin was more supple the next am. I will update this review if I have any negative reactions.\",\n", + " 'I purchased this cover January 17, 2011 when I started massage therapy school. I will also mention that when I made my purchase, it was sold as one cover for $8.50. It is a very long lasting cover! Not only did it survive 7 months of use in school, it has been part of my cover collection used for almost 2 years in my practice. It has been laundered and has held up beautifully - no rips, tears, fading or loss of softness. I am considering purchasing more now as my clientele has grown. With the current offer of $32 for a pack of 6, that makes each cover only a little over $5 each. With the track record the one I already have has, I am more than confident in purchasing more!',\n", + " 'Love these little glosses! Packaging so cute, and not at all \"gummy\". Feels like a more expensive product.
Actually perfect for sharing with my daughter who does not like a lot of color so I take those and she has the neutrals.',\n", + " 'I love the dnd product. I received 2 top coats and two base coats. Wanted 4 top coats (as advertised). They were in different bottles than what I\\'ve had before. The top coat is thicker and yellows on my \"White polish\". Oh well . . . I don\\'t use white polish often . . .',\n", + " 'Love these! The bumps on my legs finally gone! I just use on my arms on legs. Also, a great gift for girlfriends!',\n", + " 'Would not spend money again for this product, there are cheaper ones on market that do the same thing. Item just ok.',\n", + " 'This is absolutely junk!! The bit wonโ€™t even stay in. A total waste of money. Do not buy!,',\n", + " 'Good product',\n", + " 'great',\n", + " 'love this product good price',\n", + " 'Beautiful as they look hold your hair all day',\n", + " 'This product is simply over priced. Have no idea how to use it. Claim to have a video, but the web page cannot be found. Thought the tool was at least a more stronger plastic.this same tool can be found at your local hair store for $.59. Iam returning.',\n", + " 'I absolutely love โค๏ธ these ๐Ÿ˜ they are nice and heavy stay closed tight great value too!',\n", + " 'Favorite scent',\n", + " 'Would buy again.',\n", + " 'Good buy. Quality toothbrush. Simple to use, easy to replace the brushes when they wera out. Absolutely no complaints. Would use this vendor in the future.',\n", + " 'Nice, tight, assorted colors. Downside: one was broken upon receipt.',\n", + " 'Great buy at a great price and they were packed great!',\n", + " 'Donโ€™t recommend. No your nails donโ€™t look acrylic. Yes they look plastic, thin, and fake.',\n", + " 'This is the best dry shampoo Iโ€™ve found. Nice light smell, doesnโ€™t dull hair.',\n", + " \"Smells devine and it's so silky.\",\n", + " 'Too Soft',\n", + " 'I wish these were still available in multipacks. They have become really difficult to find. I love the texture of the gummies and they do not stick to your teeth.',\n", + " 'Get a great shave with this product and smell good to.',\n", + " 'they work for my daughter !',\n", + " 'These blade did not work as well as my other blades',\n", + " 'under arm deodorant exactly what it is use for',\n", + " \"I use one of these bottles for Doterra's OnGuard cleaner concentrate to clean my kitchen. I love it. It works great and sprays perfectly. The glass seems nice and thick.

The other bottle I use for an oil & essential oils mixture for wood polish. Seems to work fine without clogging.

Update: These bottles are pretty tough, but still no match for a 3 foot drop to my tile floor. I bought these eight months ago and I like them so much that I'm going to order another set.\",\n", + " \"It's a little small but works just fine. I was able to fit all my travel sized items in it with no problems, enough for a 10-day trip. Just 4 stars instead of 5 because of its smaller size.\",\n", + " '[[VIDEOID:52e8d70620797cc4ee762797131ca24c]] These press ons are extremely sturdy! Not flimsy at all. It had just enough flexibility to shape up to fit perfectly! I love them and will be purchasing again! I designed these myself!!',\n", + " 'I did a quick weave and have had the hair in for two weeks. The hair is really pretty. The only thing is the hair gets nappy near the nape area and once wet the curls do not revert. Would not recommend for long term wear only for an occasion or if you want a quick style. The pic attached is how the hair looks after wetting and detangling also before wetting. I would suggest order longer lengths so you can finger comb instead of actually having to brush the kinks out with the shorter length. It was cute while it lasted though. Remember you get what you pay for! Iโ€™m not upset I only needed a quick style so itโ€™s cool.',\n", + " 'No comment',\n", + " '100% happy thank you :-)',\n", + " \"It's a little... weird... It's the only word I can think of to describe it. It works, and not it pumps up the volume of your hair, but it also adds a great deal of stickiness. Also, it's delivery method is a little odd. Blowing powder into the root of your hair isn't a strange thing per se, but this doesn't seem to deliver it in an even flow. Probably will not purchase again. I love the other Cake products though! The hairspray for example is terrific!\",\n", + " 'Not good',\n", + " \"Love, Love Love this brush. Dogs don't mind it and it is so easy to clean with a bush of the button. Highly recommend\",\n", + " 'Smells divine!',\n", + " 'Was looking for a good shine shampoo and conditioner. This did exactly the opposite. Made my hair super dry and dull.',\n", + " 'Either my head is too small or these are HUGE.... They fall off after a few minutes of low intensity activity ๐Ÿ˜’',\n", + " 'I donโ€™t like them at all they stretch but I would say a little too much... They donโ€™t stay to the hair... I wouldnโ€™t recommend',\n", + " \"I love these eyelashes. I especially love that they offer the eyeliner in brown, black and clear. It's also great that I can wear my favorite eyelashes that normally require glue with this eyeliner without the need of glue. The eyelashes included in the kit are a good everyday eyelash. I also like that I can purchase their eyeliner separately if I want instead of having to buy the kit again. I've worn these lashes all day and even slept in them a night or two just to see how well they'd hold up. They held up amazingly. I've purchased an additional black and clear eyeliner to go with my kit. I prefer these over the magnetic eyeliner with magnetic lashes because it concerns me that the magnetic eyeliner may be found to have adverse effects at some point. Oh, additionally, this eyeliner goes on so well as a good as the adhesive works with the lashes it doesn't have a tacky feeling on your eye. With the exception of the eyeliner holding the lashes in so well, you'd never know it has an adhesive to it. This is my absolute favorite lash kit ever. It's worth the money. You won't regret this purchase.\",\n", + " 'Linestone lost.',\n", + " \"Nice little kit for the price. I don't believe it's a quarter jaw...too big.\",\n", + " 'The pattern was excellent. The elastic used to make cap stay on the head should be covered . It fit well but irritated the scalp around the hairline.',\n", + " 'Worth the money and very comfortable',\n", + " \"The only mousse I've ever used that really gives my fine hair volume as promised. Have used it for years and won't use anything else because there's no point.\",\n", + " 'Makes perfect curls. You can go spiral or just wavy. Saves me alot of money on a perm cause now i can go strait or curly.',\n", + " 'I love this! Usually these are about $5 each, this is a wonderful price for the amount you get',\n", + " 'Smells so nice and my hair quality enjoys these too.',\n", + " 'Thick gel that helps your hair look fabulous while holding it in place.',\n", + " 'GREAT PRODUCT!! GREAT PRICE!!!',\n", + " 'The colors are great, the price is out of this world!! I now have a color for any outfit!!',\n", + " 'Great with the Halloween display.',\n", + " 'Ehh. Foil with soaked cotton balls accomplished the same and have a more secure grip.',\n", + " 'I actually like the way this one sprays better than CT. Lasts just as long, totally impressed. I got 3 bottles for less than 1 CT. Iโ€™m sold!',\n", + " 'It makes my eyelashes a lot longer, saving me from having to wear falsies all the time. It is waterproof, but it is a little difficult to take off. I have tried all kinds of remover. The best way I found is to put a warm washcloth over my eyes for a few minutes and then try to remove with makeup remover. It is a bit wet when you first get it, so you really have to drag off the excess before applying. After a few weeks, it is easier to apply. It is still better than any mascara I have used.',\n", + " 'I like creams better because they are easier to blend. Once you put this on it stays for sure but I wanted a little more play to blend. It needs a view more colors like pink and green to help Camo then it would be even better',\n", + " 'Sorta dumb looking for a woman my age.',\n", + " 'I gave this to my son for Christmas and he really seemed to like it!',\n", + " 'I really like these. I love that I got 2. I put one in our camper for camping trips and the other one is in my bathroom. I use it daily!',\n", + " 'Love this conditioner! Makes my hair soft and tangle free!',\n", + " 'Love this product',\n", + " 'Love love love this eye shadow. It is nice to find a company that does what it says. Now I am a very seasoned, long timer eye shadow wearer so my cabinet is full of tried and not true eye shadows. This company is perfection. This eye shadow is a definite for sensitive eyes. It is soft, smooth, and long lasting. The color scheme it current with fashion. And the price is fabulous.',\n", + " 'Beautiful colors perfect for evening. Green eyes really pop',\n", + " 'These fall apart easily',\n", + " 'A lil runny but works well',\n", + " 'Helped my nails',\n", + " \"They chose the colors so some might not be what you want but my daughter's did.\",\n", + " 'The color was pretty but they were frizzy',\n", + " 'A little bigger then the last pair I bought from Amazon and just as sharp, pleased.',\n", + " 'Very smooth, blends well',\n", + " \"Chose warm vanilla and the fragrance is wonderful but it did not last not last 72 hrs.
The product is too creamy and never dried on my skin.
It didn't prevent wetness or odor so was a total waste especially the $17 I foolishly paid for it.\",\n", + " 'This is only good for super dry skin. It makes my skin super oily and shiny and it doesnโ€™t feel so good and itโ€™s not very breathable',\n", + " 'This is probably only good for extremely oily hair and probably oily hair would have a problem with it. It dries my hair so much I have to use a second conditioner to make my hair feel ok',\n", + " 'The packaging is cute and itโ€™s easy to use. It feels good when I apply it. But thereโ€™s really no result from using it. The price is very high and I wouldnโ€™t buy it again',\n", + " 'I donโ€™t like the texture of it and it has this shimmering things in it which is weird. And it doesnโ€™t do anything for my eyes',\n", + " 'Itโ€™s easy to use and but a little hard to absorb. Thereโ€™s no scent and one bottle will last a long time',\n", + " 'This set is perfect for Christmas season! It can be good for your female friends. If contains a great combo of stuff like tumbler and candles. The design is great!',\n", + " 'The bar soap is extremely expensive and it doesnโ€™t worth the price. Itโ€™s very small and will probably only last two weeks top if you use it every day. The scent is very strong and disgusting',\n", + " 'I donโ€™t see any result from using this. And they shouldnโ€™t sell it for money as this is supposed to be a free sample',\n", + " 'Use this stuff a lot - always ordering more as I use it frequently.',\n", + " 'well made, looks great, priced right',\n", + " 'My pets donโ€™t mind this brush because itโ€™s gentle. Works well and easy to clean. Recommend',\n", + " \"These caps are very small. Even though my hair length is short, the cap barely covers my head. If I had hair longer than my collar, it wouldn't fit at all.\",\n", + " 'This product is great. It is easy to use and lasts about 4 weeks. I highly recommend it.',\n", + " 'My 15-year-old daughter loved these. It didnโ€™t take long to get here and it has everything she needed to give herself a beautiful manicure. Would definitely buy it again.',\n", + " 'Use this everyday !',\n", + " 'I get so much compliments every time i wear one of these hair clips. it is very sturdy. I was pleasantly surprised. Just wished it came in a storage case and not plastic bags. However, this can be corrected by buying a small storage case for it',\n", + " \"The 'mix' is more clear than red. The glitter is too big to be in a nail polish.\",\n", + " 'This topper is comparable to one for $9.99 on the Asian websites. The color is fake, the hair is fake, and itโ€™s not worth a tenth of what was charged. Donโ€™t waste ur time๐Ÿ˜ก',\n", + " 'I had ordered for a fair complexion and was sent make up to make me look black and white ... no tones...no colors.',\n", + " 'Works well',\n", + " 'The smell is wicked, not a smooth powder',\n", + " 'Hard plastic pinches sides of face',\n", + " 'I have bought this for years, it works fantastically in a foaming dispenser. I keep one by my kitchen sink to use when I am cooking and messing with raw meat. It also helps remove odors. Since Covid19 I use it to wash my hands, arms and face before going out. I originally came across this when I had surgery ( I had to wash with it the night before and the day of with it) I also got a friend to start using it for diabetic foot care. It kills off fungus so helps prevent cracks and infection.',\n", + " \"This thing works GREAT considering how inexpensive it was. It's quite loud at full power, but you can adjust the speed up and down depending on your needs. Most importantly, it effectively sucks in dust when you file over it, helping to keep down the scattering of nail dust all over yourself, your clothes, your work surface, etc.\",\n", + " \"Crest Whitestrips are one of the most popular among the store brand tooth whitening products. They were introduced to the public in 2001 and they have been satisfying customers ever since. They work by concentrating special whitening ingredients like peroxide directly against the teeth where they can penetrate the surface for a full thirty minutes. Repeated usage for fourteen days should result in significantly whiter teeth.

Crest Whitestrips claim that these strips can be worn and used any time and that, once in place, you can go on with your normal daily routine for 30 minutes while the strips have the opportunity to work. It is true that you can do what you want, but there are certain activities that are not easy to do with one of these strips in place. I'm one of those people who has a tendency to want to move my tongue around when a have some type of dental object against my teeth and more than once, I have accidentally pushed the strips out of place. The gel helps to hold them in place but they can still be moved with little effort. Also, if you start talking with a Whitestrip in place there is a chance that some of your words will come out a little funny- like someone who has had a little too much to drink. I have found that, for best results, I try to do nothing at all when wearing Crest Whitestrips. The best thing to do is read a book. The time goes by quickly and it makes it easy to forget the strips are in place.

Waiting for fourteen days is frustrating and it is possible that you may need a second treatment after the first, depending on how well you stick to your 30 minute per day schedule and how well the Whitestrips stayed in place. But the results should make you happy. At first I avoided Crest Whitestips because of the price and because of the product itself. Spreading liquid gel on the teeth seemed much simpler than having to wear an object against one's teeth. I didn't like the idea of hassling with strips so I avoided buying Crest Whitestrips and tried the liquid variety in its various forms first. I finally gave in and purchased Crest Whitestrips because I got tired of waiting for satisfactory results. And I did get good results with these strips. I followed the advice on the package and used the upper strips twice per day first, then the lower strips twice per day for the next seven days. This is a good idea because you can compare the shade of the top teeth with the bottom, right after the upper treatment is completed. I could see a significant difference as all those years of soda pop, coffee, tea, and other staining drinks were suddenly washed away.

Crest Whitestrips use the same chemicals that dentist's use to clean and whiten teeth, so they are safe if used as directed. They are designed to keep teeth white for six months after each fourteen day period of usage. They also come with a money back guarantee. In order to get the guarantee. If you are not satisfied with the results, you can get a full refund of the purchase price provided you have followed the correct procedure for a refund.

Crest Whitestrips work well, but like other over the counter whitening products, they only work on natural tooth enamel. They will not whiten dentures, caps, crowns, or other artificial dental material. If you have teeth with artificial surfaces that are badly stained, you will need to seek the help of a dentist or other professional to get rid of the problem.

Crest Whitestrips are a little more expensive than the liquid whitening formulas but Crest Whitestrips are also more effective. I am satisfied with Crest Whitestrips and I recommend buying a box for effective treatment of discolored teeth. They are not as thorough as the treatment provided by a dentist but all things considered, these strips are a good buy. They eliminate stains and return your teeth to a more youthful appearance in only two weeks if used as directed.\",\n", + " 'This is a light cream that makes your skin feel so smooth and yummy. There is a faint citrus smell. It does seem to make the skin "ready to go" in the morning, so what i mean is that i seem to look less droopy in the morning. Recommended night creme.',\n", + " 'THIS STUFF ๐Ÿ‘Œ๐Ÿป I was told this would help my glitter and face gems stay on my face at festivals. I tried it out by using it before a terribly hot and humid concert, followed by a metal show after that. By the end of the night, my hair and shirt was drenched from sweat, but my eye makeup was hardly messed up. Very impressed so far.',\n", + " 'These looked great on my friend and stayed on the entire night',\n", + " \"I was going to return one but it takes 6 to 8 weeks to notice a difference and I do want to have Fuller eyelashes and eyebrows so I'm going to give it a chance even though it was a little pricey my eyelashes deserve it\",\n", + " 'Great jewelery. If there is an issue the company is on it and correcting it right away.',\n", + " 'I was hoping that it was going to be like the redkin spray and it is not.',\n", + " \"Doesn't last\",\n", + " 'These were purchased das a gift, so cannot review how well they work, but seem to be very good quality and the case is beautiful.',\n", + " 'Works good',\n", + " 'Really like this eyebrow gel. The color is a perfect match.',\n", + " 'Betty Dain has been around forever. The length of time in the business speaks for itself.
This company always delivers just what I ordered, no hidden costs. Good quality items and fast shipping.
Only one thing I would change is I would replace velcro with snaps and not raise the price.',\n", + " \"My daughter loves these but it's too greasy for me.\",\n", + " 'Shipped and arrived when expected, is what its supposed to be, does exactly what it should, no complaints.',\n", + " 'Crappy & unusable.',\n", + " \"I needed a brown for nail art. I really only care for polishes with holo in them. It is a pretty color. But it's pretty thin, takes about 3 coats for opacity and the holo is very scattered and barely visible. I think i'm going to try an indy brand and see if I can find a better holo. Don't get me wrong, if you are looking for regular polish with that little something extra, this is a great polish. If you're looking for an amazing holographic polish that happens to be brown, meh, this isn't it.
Arrived quickly, in excellent packaging. Protected by bubble wrap and bubble mailer. Excellent seller.\",\n", + " 'It dries quickly, cleanly. It is holo...what more could you possibly want from a top coat?',\n", + " \"Didn't do much for me. Had used other product but Amazon quit selling and that worked.\",\n", + " 'Cheap and breaks easy',\n", + " 'great',\n", + " 'These scissors are no where near sharp enough to adequately cut hair. They are a heavier scissor that maybe could be sharpened, but why are they sold so dull? I have had little to no use for them.',\n", + " 'I normally use another brand of Argan Oil shampoo and conditioner, but due to it being so pricey, I was looking for an alternative. This one does a good job of cleaning and conditioning your hair, but with my other one I can run a comb through my long hair after using it, which I could not do with this one. It still gave my hair a smooth texture and softness after using it, so I would recommend it to anyone that has never used Argan Oil products before. I just got spoiled by my hairdresser with the expensive one first.',\n", + " 'Perfect and handy',\n", + " 'The best powder I have used.',\n", + " \"I used to use this all the time, but somehow forgot about it. Now i don't have to use detangling spray any longer. I absolutely love this stuff. Fantastic price\",\n", + " 'Item perfect...soft...buttons in right place....',\n", + " 'Gives moderate pain relief and the texture and scent are nice.',\n", + " 'It works! I had some veins in my legs lasered and got huge bruises. This cream got rid of the bruises is record time and calmed down the pain.',\n", + " 'Great for my Dalmation themed Kindergarten.',\n", + " 'Really cut. I take off pendant for different look.',\n", + " \"Really a good product and I'm very happy that it can now be purchased through Amazon.\",\n", + " \"What I don't like the next day my hair doesn't feel soft as some moisturizers. I'm sure it's because it isn't oily or greasy, which I like. Maybe adding a little oil to help maintain softness.\",\n", + " 'The compartments could be deeper to hold the Naked pallets I own.',\n", + " 'Love it. Gel even works on regular polish.',\n", + " 'I was really impressed with how nice these are for the price. They do just as great as my $25 pair.',\n", + " \"I purchased these for a party I was going to. Most of the people attended had actual large tattoo's - these were good enough to be believable at first sight (but yeah, you won't fool anyone for long). The colors were nice and vibrant, They went on nicely and they stuck! I had to scrub quite a bit to get these off (hint - use a washcloth you don't care about too much, I could never get the gunk off my washcloth). If you're looking for something that is somewhat realistic looking and has some lasting power - these are great.\",\n", + " 'I like their volumizing 2in1 better',\n", + " 'Great product, gives the air a fresh clean scent',\n", + " 'works as expected',\n", + " 'The best hair spray ever!!!',\n", + " 'great colors, every compliments the shades',\n", + " 'This has a lot of glitter and is applied easily! Perfect with every outfit because it is multicolored!',\n", + " 'connectors work great. wish they were a little bigger',\n", + " \"I don't know what I did without this brush before. I have naturally dark hair that I have colored blonde so my hair is dry, brittle and tangles very easily. Before I had to use nearly an entire bottle of conditioner just to make my hair manageable post shower. Now I barely use any conditioner. I use a detangling / leave-in conditioner spray (Unite 7 Seconds is awesome by the way) and then I brush through with this brush and it goes through without ripping out my hair and getting stuck. It's not fancy, and arrived with the black logo on the back nearly scratched off but who cares - it works.\",\n", + " 'Damn thing works. I have a very curly beard and it reallybstraightens it out. I think it might be damaging to your hair if you use it alot, so caveat emptor.
Definitely works, though.',\n", + " 'Love it',\n", + " 'I bought seven of these. Took them to a party. They all fell apart within minutes. Terrible product. I barely had mine on and walked across the room when the strands started dropping all over the floor. The next day, they were found in the bathroom, under the couch, ....and this was an alcohol free anniversary party. Come on. Do not bother.',\n", + " 'This mitt is so large that you really have to use a lot of pressure when rubbing on your tanning lotion to keep the mitt from sliding off your hand, which then causes the foam on the inside of the mitt to rip and tear quickly. This happened to me and the tanning lotion leaked through and I had orange fingers and palms for days.',\n", + " \"Completely stunning lashes. The BEST I've ever worn. I will continue to repurchase forever\",\n", + " 'I just love these refreshing masks!',\n", + " \"Makes my homemade manicure hard as a rock in no time flat! Can't imagine doing my nails without it!!\",\n", + " 'So many things wrong; where to start. First of all, the image portrays a nice silicon object that fits over your toe and provides both the toe separator AND cushioning for a bunion.

The toe separator piece is HUGE and uncomfortable. The silicon bit that is SUPPOSED to provide cushioning just flaps around even with socks. It is very bulky as well.

IF you choose to order one of these, many of these are being sold on Amazon from sellers based in China. A giveaway is the 2-3 week shipping time.',\n", + " \"Takes at least two coats for good coverage and will eventually smudge off after moderate touching. If left alone (no kissing!) it can last a while but there's nothing really standout about this product except for maybe the scent/taste which is a decent chocolate scent that lasts a short time. The matte finish looks nice but there's little to recommend about this product there's better out there.\",\n", + " 'Everyone knows the saying \"Don\\'t put anything in your ear smaller than your elbow.\" but we all use cotton buds to clean out our ears. Just about every one of these came apart. One I had to have a friend pull out with a pair of tweezers. I was just glad she was home. Years ago they used to make cotton buds with wooden sticks. There was a good reason they stopped and went to a more flexible and softer cardboard. I think these aren\\'t the safest cotton buds on the market. I really don\\'t like these buds, they come apart, the wood doesn\\'t flex and is thin and almost pointy. Not a fan.',\n", + " \"I tried this every day for a couple weeks. I stored it in the fridge and went over my face with decent pressure. Didn't seem to do anything? I mean the cold jade feels okay, even nice, against the skin but I didn't see any real benefit. Maybe it needs more time? I'm not sure. . .\",\n", + " \"Noisy, can't really heat the water, barely keeps it warm. But the absolute worst part of this foot bath are the rollers that are supposed to massage your feet. These things are HARD plastic and actually are sharp in places. I tried them for a few seconds then tore them out and throw them away. They HURT badly. Who could design such a thing? the catches the rollers mounted in are not much better as they stand, sharp and hard, into your feet. I guess you could cut those out, maybe, but this thing isn't worth the time or effort. Look elsewhere for your foot care needs this painful thing isn't the one.\",\n", + " 'Smooths out the skin, makeup stays on longer.
I would not be without Mehron',\n", + " \"I've had this model trimmer for about 2 years now. At first, it was pretty good value for light trimming. But the trimmer guard is a flimsy plastic piece that easily breaks and it's difficult to find a replacement trimmer guard (no results from the Remington website) for this model. As well, the NiMH battery is pretty pathetic, not only short lasting when it is brand new and fully-charged, but NiMH battery tech has a terrible lifespan. Why any manufacturer would use it in this day and age baffles me. Unless it was about planned obsolescence all along. Overall, this is an attractive product for light trimming and delivers somewhat, for awhile, until one of the cheap components fails and you have to buy another because the battery is not replaceable nor is the guard made to last.\",\n", + " 'My favorite scent of the group. Cleans your beard great and smell is delightful',\n", + " 'Amazing, sums it up.. doesnt dry your beard out. Cleans it and smells wonderful. Great price and lasts me rougjly a month',\n", + " 'Smells nice, works great, price is just right',\n", + " 'Cleans beard and smells amazing',\n", + " \"Smells amazing. Doesn't seem to dry my skin. You know it's getting where it needs to go as it's not long before you taste it\",\n", + " 'Like the title say, if you have bangs that come to your brows or sweep across your brows in any wayโ€ฆ it will rub off. Will be returningโ€ฆ ugh',\n", + " \"The brush is really nice, good craftsmanship with a thick substantial handle. It deserves to be loved, but only if you're right-handed. The way the bristles are angled makes the brush upside-down in a left hand. Sure, you can use the long bristles, but that defeats the purpose of the angle which really does make the brush go through whiskers more easily. We Southpaws are very used to this. So many products designed to fit in a hand are made for the right hand, which makes them awkward or ineffective (like scissors) for 10% of us. When that happens, I find that I don't reach for that item as often, or I avoid it altogether, and, sadly, this fine brush sits seldom-used in my bathroom. Maybe some future version could have the peak of the bristles in the middle with an angle on both sides. You vast-majority-of-right-handers will love this brush.\",\n", + " 'Same classic filled chocolate cake snack. Tasty but a bit dry.',\n", + " 'great to clean mask and other devices. saves us a lot of $ and keeps things clean.',\n", + " 'Brush stiffer than expected.',\n", + " \"It was very painful to use! It pulled and tugged and left me raw! I couldn't use it but a minute! It didn't do a good job. I returned it!\",\n", + " \"I bought this for my son as his hair is thinning. I don't know yet how well this is helping . He did say the smell is awesome. He really likes it\",\n", + " 'Super cute! Love the mirror inside.',\n", + " 'Easy to install and remove',\n", + " 'Love the hair',\n", + " 'This is exactly what I needed. I have been pouring mouthwash out of 1.5L bottles for years, and this pump provides a consistent, metered amount, and prevents waste. I use two full pumps to provide enough mouthwash for a proper rinse, and some people might even want three (one is definitely not enough). Works perfectly, fits perfectly, and is exactly what I wanted. Best $7 I have spent in ages. :)',\n", + " \"It's ok hard to use because it is very stiff and hard to put tips in( they won't stay in)\",\n", + " 'Can barley pick up any eye shadow, they are so small , I threw them out',\n", + " 'Worked pretty well, no complaints',\n", + " \"I am highly allergic to formaldehyde, it cause me to be dizzy. Have headaches, watering eyes. Sore throat. I had all these things after using this hair condition one time. I read the remarks, and another person asked Amazon if there was formaldehyde in it, and they referred this person to the manufacturer. Located in Hong Kong, they gave the person the run around on the answer. And never did admit it. It is illegal to put it into anything here in the US. I was exposed to it through 2 different sets of sheets and one face cream. And now this hair conditioner. Ive contacted the manufacturer, but I doubt I'll hear from them!!\",\n", + " 'I was allergic to something in it.',\n", + " 'They work great especially for cleaning eye makeup brushes. Great gifts too.',\n", + " 'This is so very good for my hair',\n", + " 'So good for our hair, will purchase again',\n", + " \"It's crazy that items like these are essential now, but they are very needed. These little straps hold up well and they dont have issues of fraying mask fabric or make it difficult to remove the mask. These work very well to save your ears and make it easier to use masks for little ones that are a little too large for them.
Thank you for these!\",\n", + " \"I was really hoping I snagged a good one but this one is off the mark a bit. The blades tend to snag a little bit when cutting the hairs so it pulls a little when it cuts. I also found that it doesn't contour to the face all that well even though it has the ability to flex the blades. It also just comes with a USB cord and no plug so you have to hunt around for a plug to use. I didn't get to test the battery life as I only used it once and my face was as shaved as it was going to be with this razor.

Unfortunately, not great. It does do an ok job and if it's set within your means, it will work for the time being.\",\n", + " 'Works very well and easy to use.',\n", + " 'Works great.',\n", + " 'They were nice. Not as bedazzled as I thought..',\n", + " 'Use it everyday! A necessity for my hair routine. Holds well without greasy feeling or flaking. Wife and daughter use it on fly always and for hold too. Smell is great and container looks cool.',\n", + " 'I looked at other products and so decided to get this one. I wanted to try it and it works. Airassi is a product I never heard of but reading other very good reviews I wanted to try it. It has a Hair Inhibitor. Plus if you have any question to concerns you can email mail them for support.',\n", + " \"I bought them as a gift, but they smelled nice and the box looked great. The box could use a better cardboard, since the shipping can be rough and it had a slight dent on the side which I was able to push out. I'm glad it wasn't too bad, so I was still able to gift the box.\",\n", + " 'My favorite.',\n", + " 'Works great. Shaves easily.',\n", + " \"My hair is thick but fine. These clips do not hold my hair in place, they slide down significantly. The selection is as shown, quality ok, but they don't work for me.\",\n", + " 'Great product. Have purchased before. Will continue to purchase.',\n", + " 'Keep in mind this is a thin piece. But all I wanted was something to transition and cover my frizzy new baby hairs on the crown of my head to the rest of my hair while it grows. This wouldโ€™ve been perfect, But the color was several shades off.',\n", + " 'I would not recommend this comb. It smells awful! You cannot use on wet hair or get it wet.',\n", + " 'A great face mask for dry weather - my favorite ones on Amazon! Makes your skin feel so soft.',\n", + " 'Beautiful. Long lasting.',\n", + " 'Too big. No good directions',\n", + " 'Too thick to get sparse spots.',\n", + " 'The bristles are ok. The round ones are a little hard to hold. But for the price they are fantastic.',\n", + " \"If you open them up slightly they can be used on your hands. I mainly got them for my tablet and phone screens, but apparently there is something in them that smears. I thought they were just alcohol and water. They're OK, but nothing to write home about for my purposes. However, I'm sure they will work fine for someone who must clean off a wound or prepare a spot for an injection.\",\n", + " 'Absolutely love how easy these are to use. They absorb water well and the button to secure it works great.',\n", + " 'After using the serum almost a month, myself and others noticed a huge difference in the look, feel and luster of my dull, dry lifeless looking hair. I am glad I strayed from my usual routines of conditioners, hot oil treatments, you name it! I have combo hair/dry last 3/4 parts, with oily scalp. Olio & Crema serum helped moisture lock the dry without affecting or worsening my scalp oil amount! Happy!',\n", + " 'At first sight, this razor may cause some consternation to Transformers fans, who can\\'t be faulted for thinking that the arcitec 1090 is really the Decepticon known as \"Frenzy\" in disguise. It stands at attention like a little bathroom sentinel on its silver base, proudly announcing the shaving time on its shiny chest, the three circular razor heads seemingly following your every move while waiting to transform when you least expect it.

Even when it\\'s on the move, it can remain snugly in its futuristic-looking pod, which also has charging capabilities, and looks not unlike a cryogenic holding chamber from sci-fi movies.

From my (and my husband\\'s) experience with this razor, it would be a much better piece of equipment if it actually did something as cool as transform into something else. Unfortunately, it\\'s not much more than a pretty face, and isn\\'t for all types of facial hair (or leg hair for that matter)

Pros:

- Cool looking with a sleek, modern, hi-tech style. Fits very comfortably in your hand.
- There\\'s a display with BIG numbers to indicate how much shaving time you have left. If you ever get caught half way through your shave with no juice, then it\\'s time to see your Optician right away.
- Easy and quick to charge (1 hour). The quick charge feature for a single shave is a nice feature for when you\\'re pressed for time and out of charge.
- Aesthetically pleasing and efficient stand with suction cups to hold it firmly to the counter top. Razor and stand look great next to your expensive bathroom faucets.
- There\\'s a safety lock feature to prevent it from accidentally coming on when travelling. Also useful to prevent your kids from trying to use it.

Cons:
- It gives a reasonably close shave on coarse hair, but you have to keep going over the same spot repeatedly to achieve that. Men\\'s facial hair was okay, but the hair on the neck and chin was almost a mission impossible. (Ladies, forget trying to shave your legs with this razor.) My husband had to resort to a cheaper Norelco model to get those stubborn hairs, and the arcitec left the area under his chin and on his neck feeling irritated and sore.
- It took 12 minutes to shave, almost twice as long as compared to his other razor, even with the larger shaving area.
- The trimmer feature looked useful and functional, but proved to be in a very inconvenient position relative to the shaving heads. You\\'ll need to remove the shaving heads entirely for the trim feature to do its job, and even then, it was not very effective.
- Washing/cleaning after use was easy enough though it meant having to open the three individual cutting heads separately. A simple mechanism to pop all three open simultaneously would have been nice. In addition, the area for catching hair isn\\'t very big.
- The travel pod is a nice bonus feature, but on the big side if space is an issue. You probably don\\'t need the travel pod anyway, since the razor comes with a safety lock.
- Very expensive, and not as efficient as cheaper models.

Norelco did recommend in the manual that you should use it for three weeks without using any other razor so that your skin would adjust to the razor, but at this price, I\\'m afraid I\\'ll need instant gratification.

Amanda Richards, December 17, 2007',\n", + " 'We like this product very much',\n", + " 'These are one of the best make-up removers!!!!',\n", + " 'I use this as a refill replacement on my heat embossing pad....works great!',\n", + " 'It works ok. On my mother it is very noticeable. On myself, not much of a difference at all. Probably will not buy again. I will purchase a different product from this company but probably not this particular item.',\n", + " 'Great product! A super mascara.',\n", + " \"Did not work well on dark hair. Bought to use on dog and didn't show bvb up at all. Did not show up on daughter's hair as well.\",\n", + " \"i have been using rice paper blotters for about 5 years, and I am hooked on them, however sometimes it is difficult to find except on line. this type is really quite good- really absorbs oil on your face and leaves a light but invisible powder on your face which make it look like you've just washed, moisturized and put fresh make up on. The booklets are smaller than a credit card size and you can use these very discreetly, while at dinner or cocktails etc. No need to go to a restroom to re-apply make up. Really good in hot sunny weather when oils really pour out of your face.

My friends marvel at the results when they see me tear out this little piece of paper and gently pat my oily face. I have had to order for several of them.

I have several booklets which I keeps handy - one in the car, in a few handbags. Note - make sure you get the right shade - I am darked skinned - the Rachel is perfect. Rose is for fair or light skinned complexsions.

Great buy!!\",\n", + " 'Just what we were looking for',\n", + " 'Favorite toothbrushes ever. Order every time we need some! Packs of 4!',\n", + " 'Love these toothbrushes!',\n", + " \"This stuff smells. A lot. And it lingers for hours. I actually ended up washing my face all over again to get it off before going to sleep.

The lotion itself is smooth and didn't irritate my skin. It seems to absorb reasonably fast as well. But....that awful smell is a deal breaker for me.\",\n", + " \"I don't really have any use for the gloves included in this set. The curry comb is what I wanted. It works like it should and removes excess hair without pinching. Our donkey seems to really prefer a curry comb to any other type of brush and he likes this one.\",\n", + " \"I've been using this on my feet rather than my face. It's just too heavy and thick for a face cream. After 4 days, my heels are definitely softer.

It seems to absorb reasonably quickly, but slower than my usual moisturizer and skin cream. I can't detect any perfumes in this and that's definitely good.\",\n", + " \"Good grief. If you have thick, long hair, avoid these. The decorative bead things catch my hair and pull. Not cool. There is also less stretch and elasticity in these than with regular scrunchies- with thick hair that means these won't last long. Perhaps if your hair is very fine or very short you can make these work, but I can't stand them.\",\n", + " \"Between regular, every day germs and now Covid-19, we go through a bunch of sanitizer. It's in the cars, the house, the horse barn and luggage. We tend to use Purell in the giant wall dispensers in the house and barn, but these big bottles are nice too.

The sanitizer smells like what it is. This seems a bit thinner than the Purell, but dries quickly enough. I haven't noticed any sticky residue left behind or excessive drying of our skin. I'm taking one of these with me to West Texas tomorrow for use in the truck and cabin. It fits nicely in my overnight bag pocket.\",\n", + " \"Wipes like this are a fill in for actually washing your face with real soap and water, but they do come in handy sometimes. I was using these after working horses and shoveling stalls. The wipes are thick enough to get the grime off without tearing. However, after three days, my face broke out in two spots! My friend tried them and after three days, she says she's fine. So it's just me I guess.\",\n", + " \"I have very thick, very long hair and I work with horses and dogs daily. That means I've got a pony tail every day with a scrunchie. This one is a pretty deep green and it holds my thick hair well. The silk doesn't create friction or split ends and that's good. However, you only get one of these for the price and that is just ridiculous. This thing is no different from any other scrunchie out there except for the silk fabric and that still doesn't make it worth fifteen bucks.\",\n", + " \"As much as I hate to admit it, getting close to 50 brings lots of unpleasant changes and some great ones. One of the ridiculous things is suddenly discovering random hairs on my face. Tweezing is certainly effective, but takes forever and is tiresome.

This is the first little shaver of this type I've used. It needs a single AA battery that is not included. It's reasonably quiet when running, has a little light and is easy to hold. It is completely painless as advertised - this actually shaves rather than ripping hair out like those epilator things. It works well and I don't really have any complaints.\",\n", + " \"I'm not a big believer in all the hocus pocus claims made by every single women's skin care product on the market. They all say they will make your wrinkles or crows feet shrink or smooth out or give your 40 something face a "youthful" glow again. At best, these products moisturize, cleanse, and some provide some protection from sun exposure damage.

This serum from EB5 makes the usual claims, of course, but it's not as outrageously expensive as so many of the other brands. It's a creamy concoction and it takes very little to cover my entire face - the instructions say just use one pump and that is sufficient. There's a faint scent that makes me think of Asian food - I guess that's the sesame seed oil,but the scent fades quickly. It takes about ten minutes to fully absorb into my skin, so I am not using this immediately before going to bed. I haven't had any skin irritation or breaking out in a week. Nor have I noticed any visible difference in the overall condition of my skin and no "plumping" in my laugh lines. My face is soft and it feels just a moisturized as when I use only my regular moisturizer. So....four star rating for no negative reaction and for being a nice enough moisturizer requiring very little product.\",\n", + " 'I use this in rotation with a couple of other brands. The scent is pretty mild and it lathers richly and my hair does feel nice and clean and soft after using this for a few days. But....there can definitely be a build up if I use it for a week straight. My hair is long and very thick and after a week with this shampoo & matching conditioner I find my hair looks weighed down and flat.',\n", + " \"Performance only fair. Must use a great deal of product to hold hair in place & the hold doesn't last; inferior to Aussie Freeze aerosol.\",\n", + " 'Smells very good',\n", + " 'I wanted to try the breathable nail polish. I prefer frosts or pearls, and pinks. My favorite polish is by another company in a rose gold.

The photos included for this polish clearly look rose gold. Sure, different monitors, screens, etc etc, but everything else has been spot on, EXCEPT this polish.

First off, I love the rubberized top. It makes it so easy to handle. The polish itself flowed well and went on smoothly.

My beef is the huge color difference. I\\'ve already opened it, I can\\'t return it. It totally looks rosy and pearlized in the photos on Amazon. BUT, in reality, it is mauve, nearly purple. The color name is \"Pinky Promise\", so the minimum I expected was a shade of pink. They should change the name to \"Purple Promise\", which would be much more accurate. It is so different, I thought maybe I was sent the wron bottle. But the sticker on the bottom has the right name. Maybe someone messed with stickers?

It is not a horrible color, but not what I wanted, and very dark for me. Very disappointing. The quality is ok, but the shade is WAY off from the photo and name.

UPDATE: Found the weakness in this polish. Despite it being so dark, I wanted to test the \"breathable\" polish, as I\\'d never tried it. I have to say that it lasted really well. I put it on with no bottom or top coat, just the polish. It was still going strong, no chips or flaking, four days later.
Until I did a big batch of dishes.
I usually wear gloves to wash dishes (yes, sadly, we have no dishwasher where we live. It\\'s like the 1950\\'s). However, I wanted to test the polish, so wore my usual glove on my right hand, and no glove on the left.
Water, for prolonged time, is this polish\\'s kryptonite! I added a photo. All the polish came off the ends when my nails got super wet and soft.
But I will say the polish lasted much longer than my usual brand (Hansens).',\n", + " \"Well, I am not sure why someone would want this particular hair piece.
It is ok, and the hair feels very slick. But you only get ONE piece, so it would not be enough for most hairstyles.

I misplaced my photos, but will add them when I find them.
It is just super important to realize you do not get a whole hairpiece, but just one small clip's worth of hair. To look like the vendor photo, you would need to buy 10-12 of these.\",\n", + " 'We do not currently have any dogs, only cats. But, thought I would give this one a try.

It does a good job, but is a little large for an average cat. Ours were highly suspicious of it as well, being creatures of habit and used to their other brush! Ha!

Nice quality, but would definitely recommend it for dogs more than cats.',\n", + " 'This hair has a very interesting texture.. it is soft to the touch, yet simultaneously has a rough texture. It is not like baby fine hair, it is like thick, slightly frizzy hair.

There is not a whole lot of shine to this faux hair, although the flash on my camera added some.

You get a generous six packages of hair. There is not a large amout of hair in each package, but it is long enough to be versatile.
Please note I do not wear this type of hair - I use them for craft purposes. I was happy with both the texture and the color of this batch.',\n", + " 'This has a nice texture to it. The faux hair is nice and thick, and you get plenty of it. This would be very useful for wigs and hairpieces. I plan to use it for craft purposes.',\n", + " 'I really like how firm it is. It has all the essentials.',\n", + " 'Great powder, have been using this brand for a decade & the clear complexion powder is hard to find in my shade in stores recently . Great buy',\n", + " \"Wore for my wedding, didn't bug my skin, but came off quick in the heat!\",\n", + " \"I've been using 5-day Deodorant for years -- the original liquid one with the little pads that you apply directly. I'm sensitive to some deodorants, but I've never had any problems with this brand. I decided to give this roll-on a try, and find it works exactly the same as the liquid/pad version.

I put it on after I shower and just forget about it. Although the label says "regular scent," there's really almost no scent at all -- I'm really REALLY sensitive to scents, and I get no irritation/scratchy throat/etc. from this. It isn't the cheapest option out there, but I can't find it in the local stores anymore, so ordering online is the only way I can get it. It's worth it to me. Will continue to order and use as long as it's available.\",\n", + " 'I do a lot of crafts -- especially paper crafts -- and have several versions of similar boxes filled with small flowers, embellishments, etc.

This one stands apart from the rest. It\\'s VERY durable -- the bottom is \"frosted,\" the top is clear; the lid fits tightly onto the bottom and also sits flush against the compartments without any gaps at all; and the clasp is tight fitting and solid.

I love the adjustable aspect of this. The \"row height\" is fixed at about 1 1/8\", but the \"cell width\" is totally adjustable by moving the plastic tabs around. The tabs move easily and seat securely, making reconfiguring a piece of cake.

All of this versatility combines to make this incredibly useful for paper crafters. I\\'ve loaded mine with a collection of sequins, brads, eyelets, and flat-backed \"gemstones.\" I\\'ve shaken it and dropped it, and not a single sequin is out of its compartment. That\\'s a precision fit!

Very pleasantly surprised by this item -- I was NOT expecting the level of quality here. I\\'m probably going to be purchasing several of these to replace some of my existing boxes -- they\\'re that good!
(Sample provided for review; opinions expressed are my own based on my experience with this item.)',\n", + " 'I am very skeptical regarding the claims made on the box. On the front of the box they claim the cloths are \"designed to reduce fine lines & wrinkles.\" This claim is absolute nonsense. The box also states that the face towel is \"A 100% handmade silk face towel.\". This is false. The underside of the cloth is 50% cotton. They should put this info on the box itself, but they don\\'t. It\\'s misleading and diminishes their credibility.

The box claims that this cloth can brighten dull & uneven skin. I am skeptical this cloth has special powers that can do this on its own.

Save your money and do not spend so much for just 2 cloths that are not even 100% silk. These cloths do not offer the equivalent value for what is being charged.',\n", + " 'I have the Granite and the Plain. Definitely go for the Granite. The Plain will show white specks and other crap very easily. The Steel Granite color will not.

These mats are truly the best. So comfortable and nice. I highly recommend the WellnessMats Granite in the Steel color. You will not be sorry.',\n", + " 'I found nothing to dislike about this product. It serves its purpose, for those facilities that hand soap is not present. Great rose scent.',\n", + " 'Looked as cheap as it was you get what you pay for. I sent it back.',\n", + " 'Holds hair well in all weather not sticky and does not have overpowering scent',\n", + " 'Very weak and poorly made- wasnโ€™t strong enough to cut my acrylic nails- completely broke in half the 2nd time I used it- then, when I tried just using the trimmers instead- THEY BROKE IN HALF TOO! THIS IS AN INFERIOR PRODUCT!!! DO NOT BUY!!',\n", + " 'Love these!',\n", + " 'Only 2 colors in the variety box and both are shades of red.',\n", + " \"I agree it's very heavy and the size of a 3/4 full head hair extension but i am going to try and cut half of it off and if that doesn't work i'll throw it out. I also agree that VELCRO that is on the wrap part, my hair gets stuck in it. I think this hair thingie has potential, ya just gotta figure it out. (:\",\n", + " 'These brushes give a good massage while washing my hair. Would be great for dog baths. Soft, but sturdy. Come packed in a 2 bag sales unit.

Update, 3/15; when pressing too hard, the brush does come apart. It is a 3-piece brush, and the handle does not stay attached while using, and the middle nub brush section pushes in and comes apart. I Will need to look for a solid unit if available.',\n", + " 'Product matched description, ease of purchase, quick delivery
Will recommend to all of my family and friends',\n", + " 'I use homemade soap and bought these little sacks to make using my soap more convenient! I love all the lather they produce and have given a few away with bars of my soap and the recipients loved them, as well. I tie a loose knot in the top and when the soap runs out, I let the ribbon dry, undo the knot, load with new soap and it works perfectly. Great buy, great product!',\n", + " 'This definitely works the best. I have tried every nail Hardner on the market, I have even taken hair skin and nail vitamins which did not work. My nails are beautiful now, longer, harder. I do not go to the salon, I do my own nails, I use Color Street nail stickers. I have used Color Street for three years now and every morning I put a fresh coat of this nail Hardner on and my manicure stays intact for three weeks, and no, I donโ€™t have a dishwasher, so Iโ€™m doing dishes and cleaning and my nails still look beautiful. ๐Ÿ˜€ I get compliments all the time.',\n", + " 'No dif than all other clear coats',\n", + " 'nozzle wont work but did LEAK laying down',\n", + " 'Hate gloves idea - i use product in shower because of dye risk on surfaces- left on 5 mins but hair showed zero result',\n", + " 'My hair is picky - But this gives me HEALTHY HAIR!',\n", + " 'way too yellow and not as wrinkle friendly or moist',\n", + " \"I agree 100% with previous review. Exactly what I was about to say. I found this at TJMAXX and bought it to use on chest - to save more expensive small bottle retinol's for neck/face. Now I put it under eyes and on neck in the AM...Saving Retinol for use only at night. I will check at store to repurchase - I hate shipping chrgs. (Amazon doesnt stock much so we have to pay to ship?? No thanks)\",\n", + " 'Stays put and great quality! Being a huge lipstick fan I find this better than many expensive brands!',\n", + " 'Good price, pretty patterns and comfortable',\n", + " 'Excellent product, I just love it and so my skin, thank you',\n", + " \"This is a new product for me, I like the blue color, goes on smoothly with finger or Q-tip, etc. Will probably buy blue alone next time. Don't need other colors.\",\n", + " 'Other canned bean sprouts I bought had no label distinction between soy and mung bean sprouts. It was reassuring to be able to avoid soy.',\n", + " 'Works great, but be careful, the clippers are very sharp.',\n", + " \"I love this soap so much. I use it for my body in the shower. It doesn't dry out my sensitive skin, it's scent is really pleasant and not strong, and it seems to last a while. Definitely will continue to purchase this soap and it's worth paying $12-13 for three bars in my opinion.\",\n", + " 'Excellent product',\n", + " 'I love this little pack of tweezers. I can carry it in my backpack and always have it. The tweezers themselves are good quality and fairly heavy duty. I also really like the cat on the front lol

Happy customer',\n", + " 'Kinda small, and tight, they pull my hair out.',\n", + " 'I love the color. I have hazel eyes that change colors and this brings out the green in my eyes. It could wear a little longer and seems to fade just enough to where i feel like i need to touch it up.',\n", + " 'To greasy.....got returned',\n", + " 'Wish they was bigger',\n", + " \"This did not come in a box (I've had one before, they definitely are supposed to be boxed) and the sound that is supposed to beep at 30 seconds is broken. No. Would not reccomend.\",\n", + " \"Pro:
My cat adores this thing. He bugs me to brush him with it every night. He tries to climb onto my nightstand to remind me.

Con: it doesnโ€™t hold a candle to the amount of hair I get off him using my Hartz Groomer's Best Small Slicker Brush. The hairโ€™s also much harder to get out of the brush than with the Hartz one.\",\n", + " 'These are just small basic scrunchies but definitely worth the price for so many of them my daughter loves them',\n", + " 'Love love love this nail polish ! Super easy to use and exactly like the picture ... will be buying in every color ! Sooooo cool !',\n", + " 'Has made bathing our 3 pound shih tzu A LOT easier. We use these bottles to store diluted mixes of shampoo and conditioner in water, and allows us apply more controlled amounts of each product!',\n", + " 'Love the case, the color and works well just like the gritty emery board.',\n", + " 'I used these to hold a head piece on. Theyโ€™re fabulous as they donโ€™t tear or grip too tightly.',\n", + " 'Awful.
The brushes from a dollar store, are much better.
I waited too long, to return.',\n", + " '#21 light neutral beige, and it is a pretty good match to my fair, cool skin.

My skin: fair, dry, mid 40s, pink cheeks from Rosacea (visible veins, zero acne). I find that this has light natural coverage using a foundation brush. It tones down my redness with ease. It can be built up, especially if allowed to semi dry between applications. I really like that it has SPF (PA++++) 50. I always use sunscreen, so adding this on top of my sunscreen base is just added protection. Also perfect for reapplication & touch ups through day.

I also find that it is hydrating on my dry skin. Has a dewy finish. My natural skin comes through but looks better- more spruced up and put together looking. I do notice that the finish depends on what I use before hand. When I have used this on bare skin, it has a more mattifying appearance. When I use on top of my moisturizer and/or moisturizing sunscreen, then it has a more dewy radiant look. I prefer the latter.

Seems to stay in place. I applied some to my forearm, and it is still in place a couple hours later. I have taken my finger to try to wipe it off, and it is still there.

4 stars. I prefer it for light coverage. When it is built up, it seems to take on a grayish cast on me.',\n", + " 'I have used this before! I had used several GoMay products about a two years ago. I have liked them all, and there are some products that I have repurchased (love their aminos face wash). I remember really liking this night cream, and so when it came up as an option to try, I thought maybe it was another version, but no it is the same. I think the change has been in the company. They were entirely a Chinese brand, and now I see USA labeling- but I think it is still a Chinese beauty product. Same stuff that I know and love. Same press down dispenser container. I am copying over my old review as the info is all the same, and my experience is the same. While I dont rate on price, I am pleased at its effectiveness and how it is half the price of similar items I have used.

Safe, effective moisturizing product with promising ingredients. I am used to using several of these ingredients, and I must stress that it is important to use SPF when using anything with retinol. I saw that this has quite a list of ingredients that I am not totally familiar with, so I went through each one and looked them up. I included a short description of each (and included EWG rating for those that like that sort of information). You will note that most all have a very GOOD rating of 1 or 2. The only ingredient that has a higher number (bad) is for the retinol- and that is because of the degree to which retinol/vitamin A, by nature can absorb into the skin (toxicity) and how our skin is more sensitive to UV rays. So again, wear your SPF when using any retinol based products.

--GoMay is a Chinese (turned USA) beauty company and from everything I have used, the products have been impressive in formulation and the thought and safety put into creating it.

--Awesome, attractive container. Has a press down lid that pops out some product. Keeps it clean and safe! BUT if you want to get into the container, the lid does come off.

--Minimal scent- naturally occurring. Can\\'t quite put my finger on the aroma. It dissipates quickly, and it is really faint. Like green tea and plain yogurt.

--The cream absorbs quickly. It just soaks right into my skin. I have skin that leans dry, and I do follow up with either a hydrating sunscreen, or if used at night I add a thicker emollient. Your experience may vary.

3% active retinol-- age eraser, give it time (at least 3-4 \\xa0months of consistent use)
2% hyaluronic acid-- excellent humectant
Vitamin C, Vitamin E--antioxidants, skin brightener
--------------------------------------------------------------------------
Here is the full list of ingredients:

-AQUA \\xa0water!

-BUTYLENE GLYCOL (1) skin-conditioning agent - miscellaneous, solvent, viscosity decreasing agent, humectant, masking, skin conditioning, and viscosity controlling. Texture enhancer.FDA deems it safe.

-GLYCERIN (1-2) humectant, skin protectant, viscosity decreasing agent, perfuming, and solvent

-RETINYL PALMITATE (6-9) Vitamin A which is absorbed into skin and converted to retinol . Skin-conditioning.Concerns regarding Vit A toxicity (especially in pregnant, nursing) as well as increased damage when skin is exposed to UV rays. Wear your SPF, folks- especially when using retinol based products.

-SQUALANE (1) Occlusive, refatting, and skin conditioning

-SORBITAN STEARATE, (1) surfactant - emulsifying agent, and emulsifying

-CETEARYL ALCOHOL (1) fatty alcohol (a good alcohol that DOES NOT pose a risk to sensitizing skin), \\xa0emollient, emulsifying, emulsion stabilising, \\xa0emollient, texture enhancer

-CETEARYL GLUCOSIDE (2) \\xa0emulsifying agent,Texture Enhancer. A blend of cetearyl alcohol and glucose that functions as an emulsifier

GLYCERYL STEARATE (1) A mixture of portions of glycerin and stearic acid used as an emollient, surfactant, and emulsifier.

CYCLOMETHICONE (1) humectant, solvent, and viscosity controlling. An alcohol-free, clear, colorless, odorless, silicone liquid used as a carrying and wetting agent for personal care products.

BETA VULGARIS (BEET) ROOT EXTRACT (1) Skin conditioning

HYDROGENATED POLYDECENE (2)emollient;skin-conditioning agent. Synthetic polymer that functions as an emollient and skin-softening agent.

HYDROXYETHYL ACRYLATE/SODIUM ACRYLOYLDIMETHYL TAURATE COPOLYMER (1) \\xa0gelling agent that thickens, emulsifies, and stabilizes products and solutions. It is very easy to use in liquid form and provides a sensation of freshness followed by a melting effect on contact with the skin.

\\xa0ISOHEXADECANE (1) emollient, and skin conditioning, dry-finish ingredient with a powder-like finish.The size of isohexadecane keeps it from penetrating too far into the skin, so it can be a good ingredient to keep other ingredients, like certain antioxidants, on skinโ€™s surface.

POLYSORBATE 60 1-3, depending on usage) Solubilizing agent, and emulsifying. Helps other ingredients to dissolve in a solvent in which they would not normally dissolve. They also help to form emulsions by reducing the surface tension of the substances to be emulsified.

SORBITAN ISOSTEARATE (1) \\xa0emulsifying agent, \\xa0used to thicken and stabilize cosmetics formulation
BEESWAX (1) thickening agent

XYLITYLGLUCOSIDE (1) An ingredient derived from two water-binding plant sugars, xylitol and glucose. Its trade name is Aquaxyl. It works to improve skin moisturization by preventing water loss.

ANHYDROXYLITOL (1)skin-conditioning agent , humectant. A natural, plant-derived ingredient that acts as a humectant to help skin absorb and retain moisture

TOCOPHEROL (1) Vitamin E- antioxidant, \\xa0occlusive, and skin conditioning

\\xa0ASCORBIC ACID (1) Vitamin C- \\xa0potent antioxidant and skin-soothing agent and can improve the appearance of signs of aging and help brighten an uneven skin tone

\\xa0SODIUM HYALURONATE (1) humectant, and skin conditioning, Salt form of skin-replenishing ingredient hyaluronic acid; considered more effective for skin than pure hyaluronic acid due to its greater compatibility

\\xa0CAMELLIA SINENSIS POLYPHENOLS (1-2 depending on usage) Green tea! antioxidant, fragrance ingredient, ultraviolet light absorber, antimicrobial, astringent, emollient, humectant,

FULLERENES (1) antimicrobial and skin conditioning. A potent antioxidant that can scavenge free radicals. \\xa0is one way to slow down wrinkles and pigmentation. The double bonds in the fullerene can easily react with free radicals, soaking them up like a โ€œradical spongeโ€ so they canโ€™t react with your skin and damage it.

\\xa0ECTOIN (1) a synthetic ingredient that serves as an emollient on skin and can also have a buffering effect in cosmetic formulas.

\\xa0BUTYROSPERMUM PARKII (SHEA BUTTER) (1) occlusive, viscosity increasing agent - nonaqueous, skin conditioning, emollient, anti-aging

CHENOPODIUM QUINOA SEED EXTRACT (1) skin-conditioning agent.\\xa0 Rich in essential fatty acids. These essential fatty acids restore the skinโ€™s barrier function, which helps to keep the skin hydrated and soft. This extract also contains vitamin C and E, powerful antioxidants that can protect the skin from free radicals caused by factors such as UV radiation and pollution

HYDROXYACETOPHENONE (1) synthetic antioxidant and skin-conditioning ingredient \\xa0capable of neutralizing several different types of free radicals.

PETROLATUM (1-4, depends on usage. \"Good\" for skin care) petrolatum is a rich emollient and FDA-approved skin protectant. It is one of the best ingredients for dry to very dry skin, including around the eyes. Although derived from crude oil (thus making petrolatum a natural ingredient), it is highly purified prior to being used in cosmetics, so thereโ€™s no risk of exposure to unwanted chemicals.

HYDROGENATED LECITHIN (1-2) Hydrogenated form of the skin-restoring ingredient lecithin. Emulsifying agent, suspending agent

MYRISTIC ACID (1) fragrance ingredient, opacifying agent, surfactant - cleansing agentsurfactant-cleansing agent is included as a function for the soap form of myristic acid., cleansing, emulsifying, and perfuming

STEARYL ALCOHOL (1) Fatty alcohol used as an emollient and to help keep other ingredients intact in a formulation. NOT a drying, irritating types of alcohol (such as SD alcohol or denatured alcohol).

TOCOPHERYL ACETATE (1-2) is a form of vitamin E frequently used in cosmetics for its antioxidant benefit.

BEHENYL ALCOHOL (1)is a thickening agent used in cosmetics. It is not related to irritating forms of alcohol.

STEARIC ACID (1), emulsifier, emollient and lubricant. Helps improve the texture and consistency of other products. Creamy, waxy

BEHENIC ACID (1) Fatty acid used as a thickening agent and surfactant.

OLEIC/LINOLEIC/LINOLENIC POLYGLYCERIDES (1) binder, emulsion stabilizer, skin-conditioning agent - emollien
1,2-HEXANEDIOL (1) solvent. A synthetic preservative and moisture-binding agent belonging to a class of agents known as higher molecular glycols. It is considered non-sensitizing.

\\xa0PALMITOYL TRIPEPTIDE-5 (1) A synthetic peptide that is believed to play a role in the appearance of skin firmness Highly bioactive, deeply skin penetrating peptide (palmitoyl tripeptide-5). Has been found in-vitro studies to activate tissue growth factor (TGF-beta

\\xa0PROPYLENE GLYCOL (2) is a humectant (hydrating) and delivery ingredient used in cosmetics. \\xa0 It also helps active ingredients penetrate skin. In the amounts used in cosmetics, itโ€™s not a concern in the least. Fragrance ingredient, humectant, skin-conditioning agent, viscosity controlling

\\xa0DENDROBIUM NOBILE EXTRACT \\xa0From the Orchid family, anti microbrial, hydrating

MACROCYSTIS PYRIFERA EXTRACT (1) Kelp. Regenerating, revitalizing

ALLANTOIN (1) is a byproduct of uric acid extracted from urea and considered an effective skin-soothing and skin-conditioning agent.',\n", + " \"When the times comes to wash my face, this mascara comes off extra easy. I didnt realize how much other mascaras left behind, once I did my usual face wash (oil cleanse to start, then follow up with water based), and the mascara began to break down right away. Very pleased with that.

This SkyHigh mascara is actually lengthening. I have basic lashes, and I dont expect anything magical from mascara. But this is noticeable on my lashes, and as I was swiping it on I could see the lashes looking elongated. Not clumpy (that's good or bad depending on the look you are going for). This has more natural look. I haven't noticed any flaking, definitely no smudging. My eyes are easily irritated by makeup, and this mascara doesnt seem to bother me. I can wear it on both upper and lower lashes.

At a budget friendly price ($5 for 1, or $7 for pack of 2), it is worth trying. I would consider it again at this price. Another cheapie I really like is Essence, which has both waterproof and non waterproof options: https://www.amazon.com/essence-Princess-Effect-Mascara-Cruelty/dp/B00T0C9XRK\",\n", + " 'An adorable shower cap that fits my large head. It says it fits up to 24\" head, and mine measures 23.5\". Then I have loads of hair- semi thick, nearly waist length. It all fits! Yet isn\\'t a big bulbous excess of material either. But I am definitely pushing max space available (again, I have a large head).

I simply dont wash my hair every day, but I do hop in the shower. I dont notice my hair getting wet at all, but I dont put my head in the water even with this on. I have a spray nozzle for washing and rinsing, so I guess I am able to control where the water reaches better.

The fit is surprisingly good. The rear has an elastic portion to provide a nice fit. The spacing left over once in place is reasonable for my large head and mane of hair. I really was skeptical, but am glad I went ahead and got this. I have some cute shower caps, but none as nice as this. The little bow on top makes me feel like I went back in time to the 50s or something. Adorbs!

I dont use it for keeping my hair out of face for make up or skin care, but it would certainly do well for that too. Also, if I had pool.. while it isnt a pool cap, if I just wanted something to help keep excess water off my hair while casually wading in a pool, this very well could work for that too.',\n", + " \"Primer, liquid Foundation, BB cushion, and a flat kabuki brush. I have another Phoera kit, and I like it a lot.
https://www.amazon.com/gp/product/B093GFPFP9

I am not sure if Nude (#102) is the lightest shade they have or not, but if you are like me and have fair skin with cool undertones this may lean a little warm. It isn't bad, but if they had a better match available I would want to get that.
THEY DO!! this is for fair with pink undertones
https://www.amazon.com/dp/B07RZ6QZLJ/

The BB cushion is a tad lighter, and a better match for my skin. I do like both. I tend to like cushion over liquid, but both of these are fantastic. I really like how these feel, and despite being a little warm on my cool skin, the make up looks good on the skin. Doesn't settle into every nook and cranny, nor dry flakes.
My skin is 40+ so this is something I look for in make up.

The primer is fantastic. A LITTLE GOES A LONG WAY. Use less than you think you need lest you want a more oily look to seep through. I find that primers like this are great for dry skin, and for more dry feeling foundations.. but their foundations arent drying. So less is more with their primer.

The formula for the liquid foundation really impresses me. Staying power is good. Skin feels comfortable. Skin looks healthy. I can touch my skin after and it doesn't feel like there is make up on. Provides really good coverage with a little bit yet doesn't look cakey and fake. Can be built up. I would recommend this over dermablend, personally. All my redness disappears (from Type 1 Rosacea). To provide a more sheer wash, just change up your application- use a damp sponge to put it on, or use a damp sponge as last step to blend it in and lighten it up.

I really think it is worth the try. I wasn't even going to try this, but since they provided so much information in their product description it really piqued my interest. If you need coverage with a natural look.. try this!\",\n", + " 'Not shiny, not matte, somewhere in between. They call it semi-matte, and I agree. But anyone who has lines or parched lips, should always avoid any formulation with the word \"matte\" in it. You are better off with a lip liner and a moisturizing lip gloss or lip stick. Matte will always dry down and make the lip skin pucker a little. My lips aren\\'t wrinkled, but I can tell the formula pulls the skin together a little.

The color is bold. 06 Crush Berry appears to be a blue based red. Definitely red, like a classic red, just blue based rather than orange based. It feels super smooth on the lips, not at all tacky. Doesn\\'t feel or look dry to start, but it dries down to a matte look. Can achieve a decent level of stain with a few applications and blotting.

The first pass has a more oily look and feel to it. I smash my lips one way, and it appears to come off lips a little. Then I smash them in the other direction, and the color is there again. But once it sets, it isnt budging like that again. Any color disappearance is from drinking, eating.

The case looks and feels good. The overall product is pretty good, just comes down to wanting a bold semi matte color that will perform like most other lipsticks- wears off with drinking & eating.Even then it doesnt disappear. Just might need to even out the color after awhile. It seems to hold up to the product description. So for that (and all else), I give it a solid 4 stars.

I\\'m not in love with it, but it looks nice in pictures. Has a bright pop of color. This is not a subdued look at all. I find that it nearly matches a bold lip tint that I like by \"I\\'m Meme\"

https://www.amazon.com/dp/B091GSRN78/',\n", + " 'Smells SO Good!!! I\\'ll add in some pics as the product pictures shown here dont do this justice. The contents are in a sturdy flip top box makes it look like a gift (and was shipped in a regular box, maintaining integrity of the product box). Almost reminds me of a subscription box as the deign on the outside gives it a special look. It kinda threw me off because I nearly expected more of a generic look. I thought, ooh did someone send me something? lol. But no, I ordered this lol
Once I opened the box, a colorful, glossy card stock card with the phrase, \"Happy Birthday to You\" on one side, and totally blank on the other. This sits on top of dense, well packed brown paper grass. Each product is carefully nestled underneath. The products look good and they smell good. Really good-- not cloying and cheap. Just pleasant. The entire unboxing experience was pleasant, and I would totally buy this for someone. You know how some gift compilations look cheap? This has a classy, artsy look that I would be proud to give to someone.

This will probably be my go to gift item for anyone who enjoys these sorts of products. Set comes with lip balm, a bath bomb, a scrub, a cream, a bar of soap, and a soy candle. I\\'ll use everything. Personally, I use bath bombs in my shower as I dont take baths, or I use as a foot soak.',\n", + " 'What doesn\\'t work for my hair, works for my cats. That is our agreement. So these are pretty much a pack of cat toys as I prefer hair bands that fit comfortably on my wrist. These have plenty of stretch, but elastic is tight when retracted. Good or bad depending on needs. So too tight for me to keep on wrist. These are ok if I keep them tucked into a drawer and I grab one as I need one. They have good snug elasticity for thinner hair. My hair is thick, but I can use them for the ends of my hair when I put my hair in a braid. I dont like them for pulling all my hair back. These won\\'t be a repurchase. They\\'re \"ok\"',\n", + " 'This is a package of 15 individually packaged biodegradable wipes. All of their products come in 15, 30, or 45. This 15 pack at $8.95 makes them $0.59 each. Easy to open, all tucked into a flip top box

Excellent for on the go, for travel, for whenever. I have used a variety of Busy Co wipes, and I have liked them all, some more than others. When I selected this, I chose it after taking a look at the ingredients (how I always select items to buy or to try). So it was weird not to see direct ingredient list on this product page. I have included the ingredients here:

Water (Aqua), Glycerin, Phenoxyethanol, Sodium Benzoate, Citric Acid, Potassium Sorbate, Ethylhexylglycerin, Decyl Glucoside, Sodium Hyaluronate, Astrocaryum Murumuru Seed Powder, Aloe Barbadensis Leaf Juice

This unscented GLOW formula is aimed toward those seeking to BRIGHTEN SKIN, IMPROVE DRY SKIN, and REPAIR DAMAGED SKIN.
Not sure who is trying to use this on babies, but this product is not marketed for that use.

I use this on my hands and feet, prior to bed. Then I add my lotions. The wipe does a good job cleaning my skin and nails. Adds little hydration. Could use them being a little more damp, but they do work. I have a couple tucked into my purse in case I just need a wipe, but for the most part I am keeping these for night time use. While I think this product is ok, it isnt a must have for me, and I likely wont repurchase. But I do like other Busy Co products, and have found that they are a better fit for my needs (and have been repurchases).',\n", + " 'Nice feeling moisture boost. Lightweight, nothing oily about it to me. My dry skin loves a good hydrating toner, and this fits that need. I pat some on all over face, neck and chest. Sometimes I do this a few times to saturate my skin. Then I follow up with other products (serum, moisturizer, and/or sunscreen). Ceramides help build and maintain a healthy skin barrier. Hyaluronic acid attracts moisture (but be sure to lock it in with a moisturizer or an occlusive ingredient). Sedum provides intense hydration & minerals, and vitamins to the skin. So lots of good stuff going on with this toner.',\n", + " 'So calming, nourishing, moisturizing, revitalizing. $35? Great price point. What a treat! I recommend! Love it!

My skin: mid 40s, dry but clear skin (no acne). Minimal lines. Overall healthy save for redness & visible veins from Type 1 Rosacea (no bumps, no acne, just redness).

Reminds me of some of the thick, luscious, rich leave on night \"masks\" that I use. Really nice used alone, or paired with their real ampoule drops, or with your own routine. Just slather on, allow some time to absorb before hitting the pillow. Wake with supple, soft, dewy, nourished, revitalized skin. I\\'m impressed.

I haven\\'t had skin procedures, but this seems like a go-to item if I were to ever have something done- whether it be professional dermabrasion, laser, basically anything that leaves skin a little raw and exposed for a few days and would benefit from a more healing like cream.

the drops: https://www.amazon.com/gp/product/B07X4FDWKP',\n", + " \"I really like this OGANA CELL Peptide Concentrating Amazing Lotion. I'm going with 5 (4.5 if I could, but leans more 5 than 4) even at early impression. Sometimes you just know. I have been using it with their Real Ampoule Drops, which I rated a 4 at this time (4.5 if I could. ) as I need more time with it. However, this lotion has been easier to determine because it instantly lends a dewy, supple, perfectly moisturized skin that lasts all day and night (or night and day in my case as I have been using it at night). Anything else it is a doing for me is a bonus, and I know will take time, but right now the instant effect is lovely feeling, radiant skin.

It is a thin, light lotion but it is rich. I love how it feels, and how good my skin looks come morning. Little goes a long way. Maybe it is a combo of this and the drops (which instant absorb, and works well with this lotion). No matter, I am pleased with my experience with Organa Cell products so far. SO much so that I have been looking into other products. I am a big fan of K-beauty, and will likely buy their sunscreen soon.

Now, I have no idea what the full ingredient list. I will double check the packaging to see if it is there. I went to their website (Korean, so you will need a web translator) and they do not have the full ingredient list shown (unless I missed it). Pretty much what you see on this product page is what you will see on their actual web page. I sniffed around other merchant pages (jolse,wantitall,koreanbeautybox, etc). but just found the same info.

Real Ampoule Drops: https://www.amazon.com/gp/product/B07X4FDWKP

My skin: mid 40s, dry, CLEAR (no acne), smooth, but contend with Type 1 Rosacea (redness, visible veins, no bumps). ALL that I have tried by Organa Cell has been gentle, no discernable scent, absorbs well, and feels good on the skin. Great for sensitive skin as it has components to help protect, build, maintain skin barrier.

I dont rate based on price, we all have our own budgets. Organa Cell is pricier than most K-beauty I try, but it is still a brand I would recommend. I would like to see a full ingredient list, but I also find that it doesn't stop me from using their products and considering other purchases. Take my money, haha

If I experience anything else worth sharing, I will be back to do so.\",\n", + " 'Supremely soft. Seriously, the first thing you will notice is how incredibly soft these are. Really good quality, and attractive. I immediately recommend them, haha. Has a good stretch, fits my large head without feeling irritating (kinda forget it is on), and it stays in place. What is this sorcery?

If I experience anything else while wearing these, I will come back to update. My initial and immediate impression was just so favorable that I had to jump on a review to say so.

Currently $3.99 for a set of two. Good deal',\n", + " 'It works! Comes down to preference. I use dry shampoo often. I prefer the powder over the spray. I find they work better and for a longer period of time over the spray. Sprays tend to work quicker, so if you are not used to powder variety, know that you have to give it some time. So apply this, let it sit on hair for a bit before combing through. Then comb through and maybe add more. Go finish getting dressed or whatever, then finish combing hair and finishing off your style. OR apply some before bed and wake up to fresh hair.

It doesn\\'t take much. I have used other brands with similarly small containers, and the stuff lasts forever even with frequent use. This is a little smaller at 1.5 ounces, which they state is travel size-- but it will still provide many applications. At $9.99, I think the price is great (even though I do not rate on price)- and I will likely buy this again but in the dark hair option (more about that in a moment). This is a nozzle tip dispenser. Squeeze bottle to get it to disperse. Be sure to take the protective seal off from inside the cap. Mine was stuck up in the cap. It took me a few humorous attempts to get the product out from nozzle before I realized that the safety seal was caught up inside. Once I got through that snafu, all was good to go.

I failed to see that this is for \"light hair\". It is a pale yellow powder. \"This particular shampoo is optimized for light hair, so if your hair is blonde, red, or strawberry blonde, this โ€˜poo is for you\". Not all dry shampoo makes the distinction, but some do. So if/when I purchase the dark hair option (which they have, and I will link below), I imagine it will be a darker powder. But it really doesn\\'t matter!!! Many of the dry shampoo powders are white, so I figured this would be the same in terms of overall look. If not too much is used, and if it is brushed out well enough rarely is there any noticeable haze. Again, I am used to working with the powder form so it comes easy to me to get it to work.

My hair was freshened up as expected. A light lift. Not a massive amount of volume, though over course of day I noticed it seemed more full (I have very long hair, so the roots will be weighed down a bit at first). No problems. I like it. So far the product comes out from the nozzle well.

DARK HAIR option: https://www.amazon.com/dp/B084JCXT18

PS. dry shampoo can often be used as a body powder too. Look for formulas like this- just some clay and other body friendly ingredients.

Ingredients: Organic Zea Mays (Corn Starch), Organic Maranta Arundinacea (Arrowroot) Powder, Yellow (Kaolin & Illite) Clay , Sodium Bicarbonate (Baking Soda), Organic Curcuma Longa (Turmeric) Root Powder, Organic Lavandula Hybrida (Lavander) Oil

How to Use Organic Dry Shampoo

1. Give your shampoo bottle a good shake. 2. Part your hair into several segments. 3. Hold your shampoo bottle about six inches away from your head. Squeeze until you see fine powder particles falling onto your hair. 4. Using a makeup brush or your fingertips, massage your shampoo into your scalp. Brush as usual, or (for extra body), use your fingertips to massage the shampoo into your hairline.',\n", + " \"My skin is dry, totally clear (no acne) save for some redness & visible veins from Type 1 rosacea. This sunscreen feels quite gentle and does not seem to irritate my skin at all. It adds a light but effective level of hydration without feeling heavy. It is a chemical sunscreen, so zero white cast. It is thin, and goes on like a light lotion. Typical viscosity among my other K-beauty brands.

I have a wide assortment of sunscreen, of various formulations and types. It is my #1 skin care product as I use it daily all year long. It is a habit. I avoid the sun for a few reasons, so sunscreen is vital to my well being. I live in a variable climate (from dry, freezing temps to humid hot) and I have sunscreen preference depending on season and situation. I tend to prefer mineral (my fair skin can handle any white cast) but do utilize chemical sunscreen often.

I am going to like this for basic daily summer use. I tend to reduce my morning skin care routine down to a basic wash or splash of water and a moisturizing sunscreen. Since this offers SPF 50 (P++++), I know my skin is going to be pretty well protected. Since it feels like a moisturizer and goes on clear, I can skip my other skin care if I want. I tend to skip morning skin care in the summer because I am likely to just sweat it off anyway (I have a more involved night time routine to make up for it). So a sunscreen such as this is easy to use, makes my skin feel good, and easy to reapply throughout the day. I dont wear make up usually, but for sake of review I used it under a light foundation tint. Seems to play well- I didnt notice any rolling/pilling. I'll use it up. I have also used it over other skin care (hydrating toner, serum, light moisturizer) and it worked well on top of all that too.

Not sure yet if it will be repurchase. I do like Fascy Lab products, so it's a contender. Worth trying anyway
4.5 stars

Active Ingredients:
DIETHYLAMINO HYDROXYBENZOYL HEXYL BENZOATE 2.0%
BIS-ETHYLHEXYLOXYPHENOL METHOXYPHENYL TRIAZINE 1.0%

Inactive Ingredients:
WATER, BUTYLENE GLYCOL, C12-15 ALKYL BENZOATE, METHYL METHACRYLATE CROSSPOLYMER, 1,2-HEXANEDIOL, NIACINAMIDE, BEHENYL ALCOHOL, POTASSIUM CETYL PHOSPHATE, SODIUM ACRYLATE/SODIUM ACRYLOYLDIMETHYL TAURATE COPOLYMER, POLYISOBUTENE, AMMONIUM ACRYLOYLDIMETHYLTAURATE/VP COPOLYMER, SILICA, ADENOSINE, CAPRYLYL/CAPRYL GLUCOSIDE, DISODIUM EDTA, SORBITAN OLEATE, SODIUM HYALURONATE\",\n", + " 'This is a gommage!!! The most gentle of all the physical exfoliation out there. If you haven\\'t tried it, I highly recommend. I also highly recommend anything by Easydew. Good stuff! Know that this is meant to clump! Not supposed to have lather or creaminess. I had looked at the ingredients and some of the description and I suspected a gommage. The directions on box say to use on wet face and that it will lather. It doesn\\'t. There is some clumps, but not as much as if it were used on a dry face, which is what is expected from a gommage. We want glorious clumps! For best results use on a clean dry face, not a wet face. I have tried it both ways, definitely use on dry face. Works but not as good on wet face.

So use a generous amount. Just pat it in all over. Let it sit a moment, then massage it in in gentle circular motion. As you do so, small clumps will form. This is a combination of product and grime and dead skin cells. Basically, a \"gommage\" is like an eraser on a pencil, and your skin is paper. The graphite marks are dirt and dead skin cells. The product once applied is like that eraser-- it is removing those \"marks\". What happens when you use an erase? You start to see balled up pieces of eraser mixed with the graphite/pencil marks. That is more or less what is happening here. Those balled up pieces are a mix of product, dirt, and cells. Rinse, and carry on with rest of your routine. It is a very gentle \"peel\". And quite effective. But less so when used on wet skin-- the ingredients just can\\'t grab the gunk on face as well. I\\'m surprised there is such a discrepancy in instructions.

Instructions on container:
\"How to use:
Apply desired amount of peeling gel and work into a rich lather by wet hands.
Gently cleanse by massaging thoroughly over face in circles, avoiding eye contour.
Rinse off with lukewarm water.\"

But the pictures clearly show what is expected--balled up bits/clumps.

SO, it it may be a matter of terminology/language. Easydew has some wonderful products, and this is a good product that I will use maybe 2x a week. I love how smooth my skin feels and that it doesnt feel parched afterward.

FULL INGREDIENTS
Water. Glycerin, Cellulose, Butylene Glycol, Dipropylene Glycol, Pentylene Glycol, 1,2-Hexanediol, Carbomer, Tromethamine, Caprylyl Glycol, Polysorbate 20, Betaine, Fragrance(Parfum), Disodium EDTA, Glycine Soja (Soybean) Seed Extract, Dipotassium Glycyrrhizate, Alcohol, Caprylic/Capric Triglyceride, Hydrogenated Lecithin, Octanediol, Ethylhexylglycerin, Sodium Stearoyl Glutamate, Ceramide NP, Panthenol, Theanine, Milk Lipids, Sodium Ascorbyl Phosphate, Glutathione, sh-Oligopeptide-1, Capryloyl Salicylic Acid, Protease, Phenoxyethanol',\n", + " \"I'm pleasantly surprised by this Almay Length & Lift mascara. My litmus test to a good mascara has been reduced to simply whether it irritates my eyes or not. As for lengthening, lifting, volumizing, etc is meaningless in comparison. This DOES NOT IRRITATE (!!) YAY!!! Also, the blackest black is wonderfully black; makes my brown eyes pop. My lashes are well coated, making them look thicker, and there is a lift that I greatly appreciate as my lashes otherwise angle downward. Length is notable too. My lashes are nomrally ho-hum. Not thick, not thin, not long, more on short side, and angle down. This mascara is pleasing me. I dont care for make up except for mascara, but I rarely find one worthwhile. THIS IS MY NEW FAVORITE!

I'm feeling so vain. I keep looking in the mirror at my new found eye lashes!! haha!!

this product is hypoallergenic and ophthalmologist tested.

PS. Pics are of mascara only. No other make up. I realized that this darkens my lash line enough to look like I'm wearing eyeliner. I'm not! :)\",\n", + " 'Hopefully the bottle I received was an oversight in aging inventory. My bottle was hard to get open, and once I did I could immediately tell that the oil had oxidized. Totally unusable as it was truly rancid. The oil was thick, all cakds up around the topper, and the bulb dropper was rock hard. I was unable to squeeze it. I think the dropper had dry rotted, then that allowed air into the bottle, leading to a rancid product. It was evident not just based on looks, but also that super special aroma of a rancid oil. Too bad, as I love seed oils for use on body, face, and hair. This had to go directly into garbage. Not at all usable as something with anti-oxidants become PRO-oxidant when exposed to air. This is going to do exactly the opposite of what you want. Again, I give benefit of the doubt. I imagine it was a bad bottle and hopefully not at all what anyone should expect. Even so, I have to rate what I have.',\n", + " \"I've used fiber lash mascaras before- they usually have a pronounced effect, and is why I wanted to try this Kissio Derol mascara. The thing is, it doesn't do anything for me. I am perplexed. I applied the primer (comb brush with hairs/fibers), then followed up with the bushy brush mascara. And.. nothing. I can not see even a miniscule amount of added volume or length. Not even more than a basic mascara. Initially it had not bothered my sensitive eyes for the first few hours but then my eyes started getting itchy and irritated like they had something in them-- the fibers were falling off into my eyes! My eye where it was most bothered was red. I'm done with trying mascara unless it is a known brand.
Sad :(\",\n", + " 'I\\'ve only just begun using this, so this is a first impression review. I am fairly familiar with the active ingredients and understand how they work (and that they do work, so I expect this to continue that). The new part is the pearl extract, which has both immediate effect and longer term use benefit. I can attest to the immediacy, and it will be with using this for greater amount of time to determine if it a repurchase or not. As I learn more, I will share more. Here is a break down of what is in it and what to expect:

BLANCHET GLAM PEARL RADIANCE CAPSULE SERUM is a supremely light weight gel serum with hint of floral scent from lavender, geranium, rose, and sandalwood. Barely detectable. A little goes a long way. This weightless serum adds a mild level of healthy sheen. Korean Beauty emphasizes healthy skin, hydrated skin, supple skin, dewy, glowing skin. It is never matte. So while you could cover this with your foundation or powder, KB is all about letting natural skin shine through. The gentle, mild barely there sheen provides more of a glass look than a shiny look. Subtle. As for the rest... The primary active ingredients are NIACINAMIDE (2%) and ADENOSINE (.04%).

NIACINAMIDE is a skin care work horse. It provides a variety of benefit to all skin types, ages, and concerns. It is a water-soluble vitamin (B3) that works with the natural substances in your skin to help improve skin barrier, fix past damage, visibly minimize enlarged pores, tighten lax pores, improve uneven skin tone, soften fine lines and wrinkles, diminish dullness, and strengthen a weakened surface. As I hone in on ingredients that pack the greatest punch, niacinamide has stood out as a must have ingredient in my skin care routine. I especially like it for its ability to brighten pigmentation. It also is one of few ingredients that work well with other ingredients without concern for contraindication or nullification. Skin care can get tricky, and this ingredient is just so easy to work with- so go ahead and use it with retinol, peptides, acids, etc. Niacinamide simply helps skin be healthy and look healthy and radiant. As with most skin care, it can take several weeks to several months of consistent use to see changes. This serum will help over time, but other ingredients provide an instant radiant glow.

ADENOSINE is a rising star in anti aging products. There are studies that demonstrate that adenosine is an effective ingredient for improving the appearance of wrinkles, in both the eye and mouth area. Interestingly, adenosine directly affects the production of type I and type III collagen in the skin by binding to A2A receptors in fibroblast cells. So if it can help boost (or at least maintain) collagen, and help collagen from breaking down (collagen is what keeps our skin plump. Compare your 45 year old face to your 18 year old face, if your face now looks \"thinner\" despite no losing weight, it is the decrease of collagen that has produced that look). Since adenosine has been shown to stimulate the production of collagen, applying it topically can help to prevent (and somewhat even reverse) wrinkles. *thumbs up*

80% FERMENTED PEARL EXTRACT is rich in amino acids and trace minerals that are highly moisturizing, soothing, and brightening. I must say, this is something that is new to me. Before this product, I had no idea that there was a use for pearl extract. It is used in topical skin care products as well as for use internally. I really dont know much about any of this, but a cursory search led me to a few interesting bullet points:
-Increases skin\\'s collagen production
-Helps repair skin\\'s damaged cells
-Lightens skin\\'s tone and improves blemishes
-Diminishes fine lines and wrinkles
-Controls oil and shine
-Reduces pores and promotes smoother skin
-It has soft hues which shift subtly from direct to side views

PURPOSE
Skin Brightening
Anti wrinkle

Uses
High-intensity brightening lotion with 80% of fermented pearl extract in capsule technology

INGREDIENTS:
ACTIVE:Niacinamide,Adenosine
INACTIVE: water, dipropylene, Glycol,1,2-Hexanediol,Agar,Hydroxyethyl Acrylate/Sodium Acryloyldimethyl Taurate Copolymer,Synthetic Fluorphlogopite,Titanium Dioxide(CI 77891),Polyglyceryl-10Laurate,Polyglyceryl-10Stearate, Ethylhexylglycerin,Hydrolyzed Pearl,Ocimum Basilicum (Basil) Oil, Elettaria Cardamomum Seed Oil,Pelargonium Graveolens Flower Oil Lavandula Angustifolia (Lavender) Oil,Citrus Aurantium Dulcis (Orange) Flower Oil,Olea Europaea (Olive) Fruit Oil,Pogostemon Cablin Oil, Rosa Damascena Flower Oil,Rosmarinus Officinalis (Rosemary) Leaf Oil Santalum Album (Sandalwood) Oil,Glycerin,Propanediol Hydroxyacetophenone,1,2-Hexanediol ,Centella Asiatica Extract,Butylene Glycol,Propanediol ,Portulaca Oleracea Extract,1,2-Hexanediol Centella Asiatica Extract,1,2-Hexanediol ,Panax Ginseng Leaf/Stem Extract Moringa Oleifera Leaf Extract,1,2-Hexanediol , Hydrolyzed corn starch Beta vulgaris (Beet) Root Extract,Glycerin,Bifida Ferment Lysate, Glutathione,Plankton extract,Disodium EDTA,Tromethamine Acrylates/C10-30 Alkyl Acrylate Crosspolymer,Xanthan Gum',\n", + " \"This review is for the foot wipes only. I was intrigued as I do foot masks once a month, and I am always otherwise giving my feet attention every night. Sometimes I take a wash cloth to them, so these wipes are rather convenient when I am sitting in bed ready to lotion up but didnt take a wash cloth to them yet. These are quicker, easier, and nicer feeling than a wet rag. These aren't all that wet but I managed to wipe down both feet effectively enough. 14 wipes, individually wrapped. Suggested that only one wipe per foot.. so seven uses from this box.

The individual packets are convenient but wasteful if not using them on the go. I dont know how much benefit they offer beyond a basic wipe down. Non irritating, non drying. Not loving them enough to be a repurchase.\",\n", + " 'I like the shampoo and conditioner a lot- leaves my hair soft, manageable, and healthy looking. I added in this serum as I hoped to gain hair density or at least reduce loss (or reduce cycle frequency and/or duration). I dont have trouble growing my hair, I have trouble keeping it. So my hair is long, but much less dense than previous years. I transitioned from minoxidil to this. I wont do that again, as any gains I got from minoxidil were lost-- and I do contribute some of that to not using this as consistently as I did that. I\\'ll explain what went into that below. This serum helped the condition of my hair and scalp, so I think it works well with minoxidil instead of in lieu of it. I likely wont continue with the serum for a few reasons.

1. there was no instruction as to how to use this product. It is a dropper bottle, and I pretty much just used it like I did with minoxidil-- massaged whatever I pulled with dropper and distributed all over scalp, primarily at crown. Was this the correct way to do it? no idea. *

2. It does say to apply to clean hair. Well, many of us do not wash our hair every single day. I have long curly hair that leans dry and there is no need to wash it daily. So I am either applying this to unwashed scalp daily or it only gets applied a few times a week. Hence the lack of consistency. So right here it eliminates some would-be users if it has to be on a fresh washed scalp.

3. the dropper is uncomfortable. I do not want to drop it from the dropper. I want to run it across the scalp so as to keep it from getting on my hair. The dropper is a little sharp feeling (at least my bottle that I received). I like the dropper style, and my thought is that if I were to buy this again, I would use a dropper from an old minoxidil bottle instead.

4. How long should this bottle last? Since I had no idea how much I should use, I often wondered if I used too much or too little. Any new hair treatment needs to be given 4-6 months of consistent use to see results, if any. I know the shampoo and conditioner helped, and this serum has great ingredients that will help existing hair and scalp health.. but the inconsistency on my part from lack of instructions as well as expectation of using on fresh washed hair made it impossible to see if I could get benefit from it.

* \"It is best applied to damp hair after showering. We recommend visually splitting your scalp into 4 sections/quadrants. Depending on the amount of hair, use around 3-5 drops per quadrant. I like to drop into fingers and work into scalp. The remaining amount on your fingers you can work through your hair. It is perfectly fine to use the serum many times a day. That being said, it is important that the scalp/hair is clean\" (--I saw this written in the community question section of this page. Including this on box or in a leaflet would have been greatly helpful)

The ingredients are of quality, the products work well together. I have since gone back to minoxidil, and once I have stopped the current shedding phase, I may buy another bottle to use as a support product. For that, I give it 4 stars.',\n", + " 'I first tried it on the back of my hand and was horrified. The resulting color was orange pink. Then, only because I wanted to thoroughly & accurately test the product for reviewing, I decided to put it on half of my face. I expected to see orange skin like on my hand, but oddly, this just blended into my skin as a VERY CLOSE MATCH. So I put it on the rest, including under my eyes. Not bad. Glad I put it on my face.

My skin is fair, pale, with cool undertones. What I think happened is that my hands were much cooler than my face. It is the heat of the skin that triggers the color change. It is winter, and I keep my house cool so naturally my hands were on the cool side. Skin of my face must have been just warm enough for this to work.

That being said, the color match is impressive. It comes out in a grayish white cream, then bursts into color, then recedes to a dang close color match. On me, it was just a tiny bit darker & warmer than I would normally go for my ultra pale face. It covered well and did a nice job of evening out my skin tone (I have pink cheeks from ROSACEA- type 1 redness w/ visible veins). It didn\\'t look weird. It goes on like a foundation, so plan to use a mirror to make sure that you are adequately covering your face.

I think this is better for those that do not have dry skin. I have dry skin. Even with great products used underneath, I still thought this looked a little patchy on my skin in some spots. No pilling or balling though. Stayed in place for remainder of day. It could be my lack of skill in applying make up (this is an SPF, but it needs to be manipulated like a foundation).

Overall, it isn\\'t for me, but it does seem to be a quality product. I find it to be an interesting product and might be worth the try, especially if you want some natural coverage that will even out the skin. It does cover nicely. SPF48 P++

\"Apply when finishing skincare and starting base makeup\"',\n", + " 'Three pack of individually boxed hard soap bars that smell wonderful and fresh. Quite an uplifting aroma. thyme, rosemary, sage, lemongrass..mmm. Natural chlorophyll and organic cloves create a deep green color. The soap has lather, soft clean feel. I use this as a hand soap, but it can be used all over anytime- very nice soap that inspired me to see what else they have to offer. Not knowing anything about Elsha, I learned that it is a USA company that was established in 1935 offering cologne products, and eventually perfume and soaps. These soaps are handmade in USA. Although the eagle on a flag shield screams, \"\\'merica!\", the product listing would do well to say this (their other listings do). The box that the soaps come in are gray with an Elsha sticker on it. No information as to what it is, what is in it, where it is is from, etc. If there was at least an insert of information I would feel better about buying this as a gift. The website had produced just enough information to make me feel better about trying this soap, otherwise I had no idea what was in it or where it originated. That being said, it is a good soap and I would consider it again.

INGREDIENTS helianthus annuus (sunflower) seed oil*, cocos nucifera (coconut) oil*, aqua, elaeis guineensis (palm) oil*, sodium hydroxide, carthamus tinctorius (safflower) seed oil*, chlorophyll, lavandula hybrid (lavandin) oil, rosmarinus officinalis (rosemary) leaf oil, cymbopogon schoenanthus (lemongrass) oil, pogostemon cablin (patchouli) oil, thymus vulgaris (thyme) oil, syzygium aromaticum (clove) bud*, rosmarinus officinalis (rosemary) extract, eugenia caryophyllata (clove) bud oil',\n", + " \"EDIT: one stuck well enough in the reclining/laying position, the rest just fall off if I move a smidge. I will not get these again. I had used one and thought them exactly like all the others I have tried. I had no reason to believe that the rest would be different. Then next one I tried just wouldnt stay put. I tossed it out. Tried another.. same. Tried another. Tried another.. same same. So tossed out remaining 4.

This is not the silicone masks that are just silicone and are worn overnight. It's a neck treatment, very similar to facial masks. It is a juicy serum saturated mask that gets applied to the neck. If you already use facial masks, then you know that you will be wanting to pretty much lay down or recline back a little while the treatment is in place (20 minutes) lest it possibly move or fall off. Very similar to facial masks!

The material is on the larger side, and actually covers quite a bit of neck skin.

I use all sorts of skin care products, so I cant say for sure how effective the treatment ingredients are. I do use facial masks, and adding in a neck treatment is nice-- just adds to the home spa self care experience. I love facial masks, and I think if you enjoy personal care goodies like this, then you will enjoy this as well.

Individually packed in a pleasant looking box, they could be given as a gift, or parted out and shared with others.\",\n", + " 'I fell in love with Easydew products awhile back. I do tend to use and try all sorts of products, but I have a short list of products that I really like for me. Easydew is on that list. Easydew is also a brand I trust. I just sense that it is doing what it says it is going to do. Budget friendly too. They dont use frilly words and overinflated promises. They just seem straightforward with science backed ingredients. I like that a lot. I think all or most of their products include EGF (epidermal growth factors) which I am keen on for skin repair and health.
I haven\\'t used an easydew product yet that I didnt like or love. This Repair Control Renewal lotion always feels so good on my skin. I love it for my simple skin days. It has so much going for it-- addresses a multitude of concerns- and is gentle. It is one of those lotions that just make the skin look and feel good immediately. If you have dry skin, their toner is pretty great too.

My skin: 40 something, dry skin. Clear (no acne, minimal lines) but with type 1 Rosacea (redness & visible veins/telangiectasias).

My typical routine:
morning: wash face, apply hydrating toner (sometimes use 7 skins method), serum, moisturizer, SPF (I ALWAYS use SPF, that is my #1 skin care product)
night: double cleanse (1st oil based wash, then water based wash), hydrating toner (often 7 skins method), serum/actives, moisturizer and/or moisturizing overnight \"mask\" or occlusive.',\n", + " 'Easydew is skin care that is functional, effective, and always seems to live up to the expectations. I happen to like EGF (epidemal growth factors), and if you don\\'t then just don\\'t purchase Easydew DW-EGF products. I recommend doing a quick search to learn more about \"EGF in skin care\". I\\'ve been a fan for awhile now, so I was stoked to try this face wash. I use other Easydew products with success.

My 40 something dry skin benefits from the gentle, hydrating cleansing. It has some creamy lather, kinda foamy, feels nice to massage in, and rinses clean. Skin feels good. Not taut.

Dont need much. First couple of times I squeezed out what I was used to using with some other cleansers. This is thick, and once you add in a little warm water it takes off with lather. If you end up not loving it for your face, it would make for a fabulous shaving cream and/or body wash. This tube will last a long while no matter what you use it for.

I use a two step cleansing process most nights of the week. So that means starting off with an oil cleanser to help dissolve stubborn grime and products (primarily my SPF, but make up too), then using a gentle water based cleanser to actually wash away was was broken up and left behind. Some nights I can get away with just a water based cleanser. Mornings I use just water based cleansers. So really I can use this any time.',\n", + " \"Interesting product! I have used another rose tinted sunscreen before and was intrigued enough by it to try another. This one might be even better. Let me tell you about it in terms of my ROSACEA (type 1: redness, and visible veins/telangiectasias). I would not thinking adding MORE PINK would be at all helpful to my already rosy complexion. But it does a phenomenal job evening out my skin tone. I have fair, cool toned skin so I find this is still a tad dark-- so if you have skin that is even a little darker than very pale, then this should blend in real well. Yet even with the clearly pink mask that it gives me, it looks better than pink and red splotches. I just wouldnt go out in public with this alone. SO, this got me thinking about using it as a BASE layer to another sunscreen, mixing it, or the best use.. using it under make up. It will provide a great foundational canvas for a layer of foundation. Wont need to rely on the make up to even things out. If you have splotchiness, you may like trying this out. That's what appeals greatest to me-- that it evens out my skin tone gently.

Nice smell, even coverage.. makes my skin feel really good. Semi dewy supple feel. My skin is DRY, and this feels good on, Maybe it just plays well with my other skin care products? Oddly.. it has a slight gritty feel while putting it on. Yet doesnt have a gritty feel ON the skin. Not sure what I am feeling. Its odd.. but it doesnt impact overall look, feel, or performance.\",\n", + " 'I dont love the color for me, but I like everything else enough that I am am considering trying another color. I like to keep my make up simple, so I often go for an eye shadow pencil; something I can swipe on in a single color and be done. I often go for very light colors, or even more into brown or purple. This \"chalfont 303- a shimmering shade of pearl\" reminds more of a yellow tinged shimmery champagne rather than what I think of as pearl (white leaning pink). It is definitely not a white pink, too bad. I may use it blended in with something, but it otherwise looks sallow on my fair, pink skin with blue undertones. I do however love the ease of use, how it does not irritate my eyes at all, and it just goes on so smoothly.',\n", + " \"Lovely gentle and effective balm to oil cleanser. I use it as my first step in dissolving the grime and skin care products I used during the day (mostly SPF, I dont wear makeup but rarely). I have dry skin, semi sensitive and this is soothing feeling as well as non irritating. The combo of Centella Asiatica (soothing, skin health) and Hyaluronic Acid (retaining moisture) are the clear winning ingredients in this awesome oil cleanser.

I dab this oil cleanser all over the face, then let the heat of my hands melt it into my skin. It quickly turns to a spreadable oil to massage in all over. I really like the solid balm to oils over the liquid oils as I find them easier to work with. They also seem to rinse away cleaner? I feel like I could use this Mizon oil balm as my only cleansing step, but I am rather used to doing a 2nd cleanse with a gentle cleanser to wash off any remaining dissolved gunk from the first wash. You'll have to try it out for yourself.

Currently using this gentle, clean, vegan cleanser by To Do List as my second cleanse after Mizon:
https://www.amazon.com/gp/product/B08NDJR7S4

I have a couple of double duty balm-to- oil cleansers that I like, and I would consider Mizon Cicaluronic as a repurchase.\",\n", + " \"I love Leap bar soaps (LOVE!), and was curious about their liquid hand soap. It is a 12 ounce pump style bottle with visually pleasing label. The soap comes out thick and rich. It is super luxurious feeling- it lathers significantly all the while feeling like hand cream. It rinses well and leaves skin feeling soft. Probably the most soft. Perhaps a little coating of glycerin and aloe are left behind? Yet not a gross coating. I am trying to figure out the magic of my soft, smooth, clean feeling hands on a super cold (18*F), dry day. Super moisturizing.

Oddly, I find it has barely any scent. I am used to their super scented bar soaps, and I was expecting a stronger scent to come through. I am not usually keen on perfume (causes headaches, nausea), but when a product uses essential oils for scenting (especially hand soap and house cleaners), I find it delightfully uplifting. This is labeled as lemongrass, but that isn't the only essential oil used. The profile is more complex with the addition of lemon oil, orange oil, and rosemary. I was really excited for this to have a robust citrus smell. I really couldn't tell you just by sniffing. It smells fresh and clean, but it isn't strong (and I was hoping/expecting strong). I see other reviewers mentioning a strong smell. I figured I got a weird bottle or I have covid. I actually went and grabbed my Leap bar soap to make sure I could still smell that. I can. Phew.

I'm still going 5 stars because it does have a mild fresh scent, and the soap itself is glorious. Very rich, super moisturizing lather. And it rinses away perfectly. I dont feel like I am working to get the soap off. If it did, I wouldn't like that. So there is some sorcery involved here, lol. I kinda want it as a body wash. My hands feel SO GOOD after using this. I just keep touching my hands.

One does not need a lot of soap, so feel free to just add a little to the hand. I would even go so far as to add a little water as it goes down. Or if you like this soap and have a foamer, then just a wee bit of this with a lot of water will do it.

Love their designs on the bottles.

Water, Organic Coconut Oil, Organic Olive Oil, Vegetable Glycerin, Organic Guar Gum, Lemongrass Oil, Orange Oil, Organic Jojoba Oil, Lemon Oil, Rosemary Extract, Organic Aloe Vera (Potassium Hydroxide is used to saponify the organic oils into soap, but none remains in the final product)\",\n", + " \"I like it. I'll use nearly anything so long as it doesn't dry my skin out, and even better if it has healthy ingredients. This hits those marks, and at the new low price of $5, it is a pretty decent body wash (originally I have it written down at just under $20). Obviously this is a much more budget friendly price. I have a facial cleanser by Hylunia I really like, and this has a similar feel to it. I would use this on my face while in the shower with no problems. It is gentle and non irritating!
It isn't super sudsy, but it lathers plenty enough to feel like I am covering my body and cleansing it. I always follow up with a moisturizer, and I thought my skin actually felt extra soft the next day (I take my showers before bed). Smells good!\",\n", + " \"This contains retinol, so plan on using sunscreen as well as retinol based products can make skin more sensitive to the sun. It is a dry oil, so it soaks right in and doesn't sit on the skin. Don't need much, but I tend to use a generous amount anyway since my skin leans dry. I use it on my face during the day, and I like it mostly for my neck and chest as I already have a dedicated retinol product I use on my face a few times a week at night.

There are several skin loving ingredients in this product that I like, and my skin seems fine with this product. I have rosacea (redness/visible veins) and aim for more gentle products. This contains fragrance as an added ingredient, but it doesn't seem over powering. Gentle overall.

Water (Aqua), Caprylic/Capric Triglyceride, Coconut Alkanes, Jojoba Esters, Moringa Oleifera (Horseradish Tree) Seed Oil, Harakeke Seed Oil, Phormium Tenax (New Zealand Flax) Seed, Helianthus Annuus (Sunflower) Seed Oil, Retinyl Palmitate, Caprylic/Capric Triglyceride & Pistacia Lentiscus (Mastic) Gum, Tocopherol, Fragrance.\",\n", + " 'These small bars of soap smell really good and perform well in terms of cleansing and not leaving skin feeling stripped. I like that they are made in USA, handmade in Ohio. These are not fancy soaps. They are small, but they are not necessarily travel sized. They just have a good size and shape that fits perfectly into the hand. That stood out to me on first use. I really like how well it fits in my hand. The bars are tear dropped or pear shaped. More specifically, it is shaped to be a like a defense shield. Get it? As this is meant to be a bit of an immune defense/support item.

The bars are thin, but not fragile. I can palm it and easily rub it all over without it falling out of my hand. I have been using one bar on and off for a couple of weeks now, and it isn\\'t just disappearing. There are six loose bars in a resealable bag.

The soap has a slight intentional grit to it . This adds some scrubbing action. Creates a nice lather and rinses well. The scent is an intriguing mix of essential oils. Clove, Cinnamon, Oregano, Peppermint, Parsley, Eucalyptus and Rosemary essential oils Not overpowering. Really quite nice.

It has been an odd, but unexpectedly pleasant product to use. The price is budget friendly. I find nothing bad about them or my experience so far. I may consider them again when I run out. I really think they are worth the try.

\"CLEAN INGREDIENTS - Our formula just 8 simple ingredients. Free from harsh chemicals that damage your skin like Sulfates, phthalates, parabens, or synthetic fragrances. Itโ€™s Vegan and never tested on animals.\"',\n", + " \"I have Rosacea, specifically type 1 where I experience redness from flushing and visible veins (telangiectasias). Otherwise clear skin. While topicals won't really help the veins, I can use products that help even out skin tone where it is pink from flushing. Some products can initially make my skin red, then it calms down (especially if new). This ISNTREE Cica Relief Ampoule Duo Set has not irritated my skin. In fact, it has helped to minimize aggravated skin.

The serum is extremely light. I think the lightest weight product I have ever used. The bottles are small, and I feel like I am going through it quickly. I may be using too much, I dont know. I do apply to neck and chest as well as face. I already use a product with EGF (epidermal growth factor), and I thought that maybe in serum form it would feel like a more concentrated dose. I have no idea how much Isntree uses, but this product feels like the emphasis is on the Centella Asiatica Extract. That isn't necessarily a bad thing, I am just not sure yet what I think about the performance of this product for my skin. The two small bottles would be better as 1 bottle.

--super light weight
--absorbs instantly
--not tacky
--skin feels instantly smooth (I also use some on the back of my hands)
--I wouldn't use it alone as a moisturizer, especially if have dry skin (like me)
--gentle, doesn't aggravate my skin, but that very well could differ for everyone (esp those w/ damaged skin barrier)
--contains soothing centella asiatica extract
--contains EGF- worth doing some research to see the benefits and to discount myths.
--ingredients that can help build and maintain skin barrier. Especially important for those with skin conditions where they are exacerbated by a damaged skin barrier. Got super sensitive skin? work on repairing that skin barrier before anything else.
--NO added fragrance in ingredient list. No naturally occurring scent either. I cant detect any aroma.

My skin: mid 40s, smooth and clear (except for visible veins), leans dry. I follow this up with a moisturizing SPF (their sunscreens are great) or a moisturizer if using at night.

I dont think it is bad. I really just think it is ok. I would give it 3.5 stars if I could. For me it isn't quite a 4 star product, so I am going with the middle of the road rating of 3. Your experience will vary. I think it would be especially appealing to those who prefer a weightless non tacky Centella Asiatica product. While I have zero issues with this, I am not likely to repurchase it. I have preferred products, especially for EGFs. However, if I notice anything else-- good or bad, I will be sure to update. It can take at least 2 weeks for a product to show its effectiveness, and it can take that long for the skin to acclimate to a new product. I am a little early on writing this, but my skin is used to centella asiatica as well as EGFs, and with some Isntree products.\",\n", + " \"My tin is dented. It just arrived in a warehouse mailing bag. There was no protective tape, tamper sticker, or cover, or product box... so I am not sure what this product has been through before arriving to me. Ew. I know products are sold by weight not volume, but the container really does look like it is missing a portion, as it is half empty. It is probably all there. The container looks to be a 2 ounce capacity, with 1.7 ounces of product. The product is dense, so after settling, I imagine this is accurate. But still.. between the dented can and the lack of protective seal, I am reticent to use in on my face, and definitely won't be buying it as a gift (which I was considering as I ordered this for me, and figured if i liked it then I would buy it as part of a pampering gift).

Too bad because the container otherwise is attractive, the product smells good, and the ingredients are interesting; highly nourishing & repairing for the skin. I love self care products, and doing an occasional mask is relaxing.

1.7 ounces has 3.4 tablespoons. Probably use half a table spoon to cover face. So maybe 7-8 full face applications? I guess price it out like a sheet mask. $3.75 per treatment if assuming 8 applications. More or less depending on how much you use.

I hope the company considers adding a seal or tamper sticker.\",\n", + " \"I have been pleased with medical grade Easydew products, and this is another. It is an extremely gentle creamy cleanser and exfoliator (through enzymes). Effectively cleans my skin. Sometimes I use it after an oil cleansing, sometimes by itself. My skin never feels taut or stripped. Nor does it ever feel coated. My skin always feel simply clean and fresh.
Has a light fragrance- similar to other Easydew products. It doesn't bother me- no headaches or nausea. The scent dissipates quickly enough. I have no issues with this.

My skin: mid 40s, fair, semi sensitive, dry, Rosacea (redness/visible veins).

Don't need much for it to do its job. Lovely product that I would likely purchase again.

FULL INGREDIENTS

Water, Isopropyl Myristate, Glycerin, Butylene Glycol, Cetyl Ethyl hexa no ate, Chondrus Crispus Extract, Saccharum Officinarum (Sugarcane) Extract, Milk Protein Extract, Milk Lipids, Panthenol, Protease, Ceramide NR sh-Oligopeptide-1, Hydroxyeth yl Urea, Pentylene Glycol, Glyceryl Stearate, Glyceryl Stearate SE, Sorbitan Stearate, Caprylyl Glycol, Cetearyl Olivate, Sorbitan Olivate, Tromethamine, Palmitic Acid, Ethylhe xylglycerin, Stearic Acid, Caprylic/Capric Trigly ceride, 1,2-Hexanediol, Hydrogenated Lecithin, Myristic Acid, Arachidic Acid, Lauric Acid, Oleic Acid, Sodium Stearoyl Glutamate, Sodium Ascorbyl Phosphate, Theanine, Glutathione, Dimethicone, Cetearyl Alcohol, Carbomer, Alcohol, Disodium EDTA, Phenoxyethanol, Fragrance(Parfum)\",\n", + " 'The bottle and texture is very much like a hair mousse or shaving cream, but is a wash for the body. Instead of a pump or squeeze bottle, this comes out though as pressure aerosol - also just like a mousse or shaving cream. The ingredients necessary to make this happen are Butane and Propane. They are aerosol propellents. If you have ever used mousse, hair spray, various perfumes/body sprays, air fresheners, aerosol deodorants, or shaving cream,etc.. then you are already familiar with these ingredients. They are generally recognized as safe, and are used in small, diluted quantities in skin care. Fun fact, \"These ingredients are used in cosmetics and personal care products as a replacements for chlorofluorocarbons, or CFC propellants, some of which have been shown to have negative effects on the environment\". I\\'m not a big fan of slathering my body with butane, propane, or isobutane, but I understand their use in this type of medium. So it\\'s up to you to decide.

This company does have non aerosol body wash available too..

The resulting foamy wash comes out thick, it is creamy. Because it reminds me so much of a shaving cream, that it what I have been using it for. Then whatever is left over I use on rest of body. Is pleasant smelling enough to me but it isn\\'t quite a pure aromatherapy experience for me. Clearly it uses a variety of essential oils- rosemary, orange, eucalyptus, peppermint, limonene. However, for whatever reason, it contains \"parfum (fragrance)\" as an added ingredient. As well as Alpha-Isomethyl Ionone, another synthetic fragrance ingredient. Is there not enough naturally occurring scent from the use of essential oils? I think the added synthetic fragrance is redundant and takes away from the olfactory experience.

As an actual wash, it is fine.
3 stars-- this is just a middle of the road rating. I am not in love. The experience is underwhelming. I am much too quickly going through the container. Aromatherapy experience is a little off as I pick up on something other than essential oils. Otherwise the cleansing action is fine. But.. I likely won\\'t repurchase.

I think if I really want a foam wash, I will just use another body wash or make my own wash and pour into a foaming soap dispenser.

CRUELTY FREE | NO PARAFFIN, SILICONE OR MINERAL OILS | PLANT-BASED | PARABEN FREE | VEGAN

Aqua (Water), Sodium Laureth Sulfate, Butane, Glycerin, PEG-40 Hydrogenated Castor Oil, Isopropyl Palmitate, Prunus Amygdalus Dulcis (Sweet Almond) Oil, Mentha Aquatica Extract, Rosmarinus Officinalis (Rosemary) Oil, Citrus Aurantium Dulcis (Orange) Peel Oil, Eucalyptus Globulus Leaf Oil, Mentha Piperita (Peppermint) Oil, Linalool, Limonene, Benzyl Alcohol, Geraniol, Alpha-Isomethyl Ionone, Sodium Levulinate, Sodium Anisate, Parfum (Fragrance), Hydroxyethylcellulose, Sorbitol, Propylene Glycol, Glucose, Propane, Isobutane, Citric Acid, Lactic Acid, Sodium Hydroxide',\n", + " 'Good basic sheet mask that feels cooling and hydrating. Feels nice when my rosacea has made my face feel warm (I have visible veins/redness from rosacea; no other issues). Excellent for use in the bathtub, or for a mini nap, or simply to help relaxation. Might even be perfect post skin treatment sessions that may leave skin feeling irritated.

Stocking stuffer!! I love how budget friendly this pack is. I love making little self-care packages to hand out, and while I will buy and use masks in the $5-35 range, I prefer the $1-3 masks for the token give away (think: facial mask, hand cream, lip balm, etc.. tiny cheap self care packages). I also prefer the cheapies only because I am not sure if the recipient will definitely use it, and the higher end masks tend to be more discerning in what it attends to. The more basic masks tend to be good for nearly everyone, and the resulting feeling is at least a fresh, hydrated face. So these are a repurchase for that purpose, as well as for my own use on days I want to keep it simple.

I love that it has lots of moisture. The serum can be patted in all over face, neck, chest, even elbows & hands after.

For all that it is, I give it 5 stars for this level of facial mask.',\n", + " \"I don't really have any de-puffed areas. I do have a couple of odd spots around the corners of my lips that I am trying to figure out how to attend to. I have been successful with Easydew products, so I added this into the mix to see what more it can help me with.

-I love the container. It has a cool, modern look. Applicator is precise.
-The texture is cool and gel like. It is clear.
-Very light scent
-Gentle feeling, non irritating on my dry, semi sensitive skin
-A little goes a long way, just use a little.. gently dab it on. Allow a minute to absorb before adding other products
-Key ingredients, benefits:
Epidermal Growth Factor (EGF) helps to repair skin, and Hyaluronic acid (HA) helps to attract and retain moisture.

I am currently using a variety of Easydew products, some of which contain EGF. I love how my skin feels and looks. I have only recently added this in, and I don't expect a quick change. I am using it around lips, and am considering using it around eye area. Since this can be used near eyes, I may keep it only for that area. I have their serum and moisturizer with EGF & HA. I would say from my experience with this line, is that this is more of a longer term use item. I see it says something about instant depuffing, but unless you have a real trouble spot, it may not be instantly noticeable. What I encourage is consistent use. Maybe add in their other fill up products or Repair Control EX, then use this for specific spots.

My skin: mid 40s, clear, semi dry, semi sensitive, Rosacea (redness/visible veins).\",\n", + " 'I have tried several Easydew products, and they have all been great for my skin. I always want to touch my skin in awe, and have to remind myself to keep hands away. I am pleased with this Easydew EX Repair Control Renewal Intensive Moisture; it has been good for my mid 40s, dry, clear, semi sensitive skin that has type 1 rosacea (redness, visible veins- \"telangiectasias\").

It has ingredients to help repair skin, to build and maintain skin barrier, to help brighten skin, to calm the skin, to hydrate the skin. My skin is always well moisturized, feels dewy and supple, and never ever as a problem with being irritated. I like how it feels when I first put it on, and I like how my skin looks and feels come morning after having put it on the night before.

I like it for day time or night time use. It is surprisingly hydrating. Works well under my sunscreens. Works well over other serums. While I prefer a heavier cream at night, this is instantly moisturizing enough that I don\\'t need to add anything else on top. Perhaps once the extra dry cold weather comes in, then I will add something on top. However, when paired with their hydra toner, it may be enough no matter the humidity.

It has a light fragrance (has fragrance as an added ingredient, for those who refrain). Not great but not bad. Fortunately it is light and doesn\\'t linger.

Any alcohols used in this are fatty acid alcohols and are highly beneficial to the skin, especially dry skin.

Using medical grade EGF, it contains 10ppm of EGF, which means that it contains the maximum amount of EGF allowed for a cosmetic product to give you maximum results.',\n", + " \"My skin: mid 40s, clear, dry, semi sensitive, Rosacea (redness, visible veins, non-acne).

Great ingredients that are helpful in creating and maintaining a healthy skin barrier. Ceramides are vital in this role which this product contains. As well as other skin loving, skin calming, skin repairing ingredients such as resveratrol, St Johns Wort, Centella Asiatica, probiotics, and prebiotics, peptides, and niacinamide.

Lightweight, slightly creamy, easy to absorb serum that works well on its own but doesn't seem to play well with foundation. Maybe I haven't found the right product yet to use on top. When I apply makeup, in no time the skin looks like it is peeling heavily, but it is just the product peeling off. Even when using a little. This is the worst I have ever experienced with any product. Again, it might be what I have tried it with. And by itself.. seems totally fine. Your experience may vary.

Use a light hand, as it seems it doesn't take much to cover face, neck, chest. So, little goes a long way which is a good thing.

Worthwhile to try.\",\n", + " 'This Juicy Chemistry face & body scrub is a very mild, and seemingly gentle \"scrub\" chock full of great ingredients. For rating, I am right in the middle of neither really liking it nor really disliking it (ok, maybe leaning a more toward dislike for me). The \"3 stars\" include the fact the company (and their ingredient selections) seems of high quality and may be worthwhile to check out.

I have mixed thoughts on this, so please bear with me as I try to explain.

At first glance, the small container is packed to the brim with a dark brown, dry, granular looking substance. This is primarily a combo of coffee powder and cocoa powder. I thought it was going to be a rough scrub, and immediately thought that there is no way I would use that on my face. Since it says, \"for face AND body\" my plan changed to use it on my body in the shower. However, the directions say to apply TO FACE, and allow to sit for 10 minutes/until dry. That isn\\'t happening as a body scrub. In the shower.

So now I am back to trying it on my face. It did not come with a spatula or spoon, so plan to use your own. Or scoop out with a finger.I have tried it by spooning out a bit of product and adding water, adding a hydrosol, and adding an oil. The latter makes it easiest to use through I do not know if it impeded the other ingredients. Also, it wouldn\\'t dry with oil. But it did stay in place with oil.

Any granular feeling quickly melted down, so I felt better about using it on my face. But still, not a fan of anything granular on face. Overall, I don\\'t like it for my face- I only tried it once because that is all I could handle. . It felt like it left some powder behind. I felt compelled to rewash my face to get any remnants off. Meh.

Body is fine (and is why I selected it for use). When used with all bases I mentioned, the result was a slightly oily feel. Not heavy, not greasy. Definitely a little bit of hydration/moisture. Ultimately not a fan of it for my face, but do like it enough for use on body. HOWEVER, I do not \"keep it on until it dries\" while I am using it.. in the shower. I just use it like a regular body scrub. I either add water to it, or oil. OR use a basic creamy body wash as the vehicle. Now that I think of it, even a body lotion would work (especially if you have one you dont love and want to use up). Once again, the oil (or body wash/ lotion) is easier to worth- I can work it all over body, massage it in, and as it rinses away once again that slightly oily feel is left behind (not greasy, not heavy, rather soft and light; rather nice). Make sure to rinse shower as this will splatter brown all over.

I like that the product is packed into a small jar container, and that it needs a base (water, hydrosol, etc) which can be good or bad depending on your preference. By needing to add your own, the product is more concentrated (not paying for added water,etc), but it lends just a tiny bit of inconvenience. Use in the shower is awkward. Use as a scrub mask is going to come down to preference. If you like a more granular feeling physical scrub/exfoliator this may not be for you. If you use more, you may get more of a scrub feel (I guess you could add sugar). I use less as I do not want a harsh physical scrub. For the shower, I prefer a greater scrub feel, so I use more. I am thinking now I may add this to another jar, add some cream or oil, and some added sugar for an easier to use shower scrub experience.

Packaging is nice, and pleasant to look at. Could be worthy as a gift if this seems like something someone would like.

Full Ingredient List:
Sucrose*, Coffea Arabica Seed (Coffee)Powder*, Theobroma Cacao(Cocoa)Powder*, Theobroma cacao (Cocoa) Seed Butter*, Butyrospermum Parkii (Shea) Butter*, Citrus Sinensis (Sweet Orange) Essential Oil*, Vanilla Planifolia (Vanilla) powder*, Simmondsia Chinensis(Jojoba Oil)*, Corylus Avellana (Hazel) Oil*, Coffee Infused Oil*, Tocopherol^, Helianthus annuus Seed Oil, Rosmarinus officinalis(Rose Mary Antioxidant) Leaf Extract.

\"Formulated especially for dry skin, this scrub brings together the classic combination of Coffee and Cocoa with a hint of Sweet Orange.

Cocoa has powerful antioxidant properties that help to heal damaged skin and other skin ailments. It helps renew and promote healthy cell development. Ground coffee beans gently exfoliate the skin and also reduce the appearance of cellulite and stimulate skin cells.

The fatty acids and Vitamin E content of Hazelnut oil help create a natural oil barrier that helps skin retain water and avoid drying out. It also contains tannins, a powerful antioxidant that help cleanse and shrink pores. Vitamin E also helps with collagen synthesis and reduce the appearance of scars.

High Vitamin C content in Orange makes skin radiant and also helps in collagen production resulting in supple, hydrated and age-less skin.

Sugar acts as a natural exfoliator and helps to gently remove dead skin and impurities making it radiant and softer.

Rich in fatty acids and natural vitamins, Shea Butter moisturizes the skin to relieve dryness. A super-hydrating blend of Cocoa Butter, Natural Vitamin E, Extra Virgin Olive Oil, Jojoba Oil, and Sweet Almond Oil makes skin softer and smoother.\"',\n", + " \"Quick absorbing, non greasy watery hand & body lotion. I like my body lotions to be on the thin side as I find it easier/quicker to apply as well as quicker to absorb. When I have extra rough spots, then I don't mind using a thicker emollient. But for just out of the shower lotion to lock in moisture.. I want a thinner lotion. This provides that. Yet, it is moisturizing enough to use any other time of day. Leave at kitchen sink for hand moisturizing as needed is great too. But not at bathroom sink lest someone mistakes it for toothpaste, haha. It is in a toothpaste style container. Just flip cap and squeeze.

It feels nice on skin, has no added fragrance. I like their 1513 face lotion and I like this hand/body lotion too. I tend to have dry skin, so I find both are better for me for summer or days I just a light hydration boost. Easy to use, no frills lotion that is gentle on skin. I appreciate the nourishing ingredients and that they offer a no fragrance added option. Any hint of scent is entirely naturally occurring. However, this may not be for you if you seek to avoid essential oils as is is listed at the end.

Overall it is a nice product. No irritation. No issues thus far.

Key Ingredients:
--Rose Flower Water: Helps maintain the skin's pH balance
--Organic White Willow Bark Extract: A natural exfoliant that helps reveal brighter, radiant skin; Acts as an astringent and anti-inflammatory
--Aloe Leaf Juice: Hydrates and helps to lock in healing ingredients โ€ข Hemp Seed Oil: Treats inflammation and redness

Ingredients:
Organic Aloe Leaf Juice, Organic Coconut Oil, Glycerin, Stearic Acid, Emulsifying Wax, Witch Hazel Water, Vitamin E, Sunflower Seed Oil, Phenoxyethanol, Organic Hemp Seed Oil, Rose Flower Water, CBD, Organic White Willow Bark Extract, Organic Rosemary Leaf Extract, Organic Neem Seed Oil, Organic Alcohol, Xanthan Gum, Tetrasodium Glutamate Diacetate, Essential Oil\",\n", + " 'FULL ingredient list:
Organic Aloe Leaf Juice, Avocado Fruit Oil, Organic Jojoba Seed Oil, Emulsifying Wax, Glycerin, Organic Palm Fruit Oil, Stearic Acid, Vitamin E, Sunflower Seed Oil, Organic Neem Seed Oil, Organic Rosemary Leaf Extract, Organic Sunflower Seed Oil, Phenoxyethanol, Rose Flower Water, Rosehip Seed Oil, Carrot Seed Oil, Wheat Germ Oil, Vitamin A Ester, Vitamin C Ester, Provitamin B5, Allantoin, Organic White Willow Bark Extract (Salix Alba), Organic Alcohol, Xanthan Gum, Tetrasodium Glutamate Diacetate, CBD

KEY Ingredients:
* CBD: Formulated with 750mg of CBD; Acts as a powerful antioxidant that reduces free radical damage
Rosehip Seed Oil: Moisturizes and brightens skin; Improves texture
Carrot Seed Oil: Heals and balances skin; Address fine lines and wrinkles
Provitamin B5: Stabilizes skinโ€™s barrier and helps skin retain moisture

*\"Research is mounting on how CBD helps our bodyโ€™s endocannabinoid system (ECS) increase oil production in the pores and in turn drastically reduces the appearance of fine lines and wrinkles\"
(if this is accurate, then having naturally oilier skin is indeed one way to fend off lines and wrinkles. Oilier skin tends to age better. I have dry skin, but I have been moisturizing and protecting with SPF since my teens).

MY skin: Mid 40s, very clear, very fair, minimal/no lines, supple, leans dry, has Rosacea (non-acne, just flushing and redness from visible veins). My skin loves hydration, oils, thicker heavier products.

This product:
--stay fresh, pump style tube container (think of a toothpaste container with a pump)
-- thin, light, but rich lotion.
--smooth, glides on
--absorbs quickly, no lingering sheen or greasiness.
--plays well with other products (ie; toners, serums, SPF, make up)
--gentle, non irritating.
--skin nourishing ingredients
--no added fragrance; barely there naturally occurring scent.

When I use it: daytime after serum (if I use one) but before SPF.

Quite a range of experiences and preferences, but that make sense since we all have different skin and skin care needs. So for me, I find that it is almost TOO light for my needs. Here is what I do like: I like that I can easily pair it with other products as it doesn\\'t seem to pill or roll. I would never use this at night as it is just too light for me, but it has been fine for use in my morning skin care routine- after a serum and before a moisturizing SPF. I don\\'t feel like it works as my only moisturizer, but I DO think it is worth a try. The ingredients are fabulous. While it doesn\\'t feel like it is drying, it doesn\\'t give me that dewy oomph that my preferred products can provide. Maybe I need to use it for a longer duration (sometimes that happens.. something I use for awhile doesnt seem to be doing anything but I keep using it to use it up, and at some point I notice a noted improvement).

Despite it containing a lot of different nourishing oils, I would prefer it to feel and look a little oilier. Maybe over time? I am thinking this might be good for dehydrated oily skin, or normal to lightly dry skin. I am just guessing.

I would use it to hold in other hydrating products like a thin mask. Or MAYBE on days when I just want something on and I don\\'t want to fuss.

Unexpectedly great for hands. Immediate softness. The backs of my hands feel super wonderful after applying this. The pump container makes it easy to dole out on the go. Would be great for keeping in a purse.

Since it is thin but rich as well as the ease of application makes it REALLY nice as a neck and chest cream. If this formula is supposed to increase skin oil over time, then having that added advantage applied to the neck (naturally not oil area) could be a game changer for those concerned with skin on the neck.

I think it is lovely, overall. 4 stars',\n", + " 'Individually wrapped cleansing cloths that are way better than any other I have used in the past. The material has a good strong feel, and it is large enough that it nearly feels like a washcloth. I can really get my hand on it. The packets easily tear open. The cloth, once wet becomes crazy sudsy. It has a barely there scent. I really have to sniff to be able to detect anything. Very fresh. The lather is gentle and non drying. I was surprised that my face was not feeling parched or taut afterward.

Not only for face, but it makes for a decent cleansing cloth to have a \"bird bath\" at the sink. Just wipe down everywhere you need to, rinse the cloth, rinse your body, rinse the cloth again, ring it out, use it to pat down the body.. and away you go.

I think one could get away with using half a cloth easily for just face washing as there is plenty of cleaning agent in it.

Overall it is a lovely product. I think it is perfectly packaged for occasional use, or for on the go/ travel. If I were to use it all the time, I would prefer something with less packaging. Maybe they have that... I didn\\'t look.

But for travel: definite yes. I would go so far as to use one in the shower to take care of face and entire body. The cleanser is so gentle, which is a huge draw for me and my dry/rosacea skin.',\n", + " \"My skin: mid 40s, leans dry, semi sensitive*, clear but with redness/visible veins (rosacea).

My skin has been really loving this Easydew Daily Double Hydra moisturizer. I love K-beauty products and hadn't heard of this line. I am glad to have been able to try it as it just works really well for me. I highly recommend that it is paired with their Double Hydra Toner, especially if you like using hydrating toners using the 7 skins method (apply toner in layers until skin has soaked up as much as it can). Then follow with this, and the skin feels light, fresh, hydrated, supple, smooth, plump, and oh so happy. I find that I can use it day and/or night. I really have no preference. Seems to play well with other products (SPF, serums, masks)
https://www.amazon.com/dp/B077BTR9H4/ref=pe_1098610_137716200_cm_rv_eml_rv0_dp

As someone who engages in hobby skin care, I like finding through trial and error items that I would buy again, or would be my go-to if I had to choose just a couple things. These two are my go-to items. If I don't feel like playing around with other products, or if I am in between testing products, this combo just saves my skin and makes it look and feel so good. In a time when we really shouldn't be touching our faces (and we shouldn't anyway), sometimes I can't help it as my skin just feels soft and pleasantly moist.

The bottle style is very familiar to me. Tall, thin, with twist off cap. Squeeze to get product. 2.02 fl ounces will last quite some time even when using a generous amount. Dont forget neck and chest :)

When I say I have semi sensitive, I used to have really sensitive skin- felt easily irritated, often had a burning feeling or itchy feeling. I had to learn about ingredients and figure out what bothered me. But ultimately, I learned that it incorporating ingredients that help repair and maintain the skin barrier is what helps most of all. So ceramides, occlusives, Natural Moisturizing Factors (NMF), Serine, copper, and several others.. that just help the skin significantly. Add in hydrating toners and consistent use of SPF, and the skin is looking good. Now, using harsh products can contribute to broken skin barrier, but often it is simply environmental or physical (too many exfoliating sessions, too harsh/physical scrubbing, too much sun/wind/vacillating temps). So I consider my skin semi sensitive because I am aware that I used to have really sensitive skin and now I seem to not to, but I still actively regard and address my skin in terms of maintaining skin barrier. THIS product has ingredients that help the skin barrier (NMF, Serine).

I like it a lot, good stuff. Definitely recommend.\",\n", + " 'Interesting array of ingredients. The predominant scent (and minor, initial flavor) is that of seaweed, since that it the primary ingredient. It doesn\\'t come back up in burps like a fish oil can.

I have been taking this for 2 weeks now. I did not immediately start with a full 2 caps does as I wanted to make sure that I could tolerate the new ingredients. I can. So then about a week in I began taking two caps. I know I have forgotten a dose or two, but I am through 2 of the six blister packs, and just starting my third. I am embarking on a multi pronged approach to my massive shedding cycles. I used to have incredibly crazy thick hair and over the past 10 years or so, it has greatly reduced. My hair grows fine (it is nearly waist length) but the hairs are thinner, and the overall volume on my scalp has reduced. While we all naturally shed, the amount that comes out when I am in a shedding cycle is depressing. I hope to reduce the frequency and amount of loss. SO, I am taking supplements, starting some new DHT blocking shampoo and conditioner, adding in a scalp treatment.. etc. This supplement is all together different than what I have been taking, so I am extra hopeful for its effectiveness. It am currently either in an \"off shedding cycle\", or my approach is working. I don\\'t want to claim yet that this is working as I think the benchmark for noted improvement is 3 weeks. BUT I\\'m not too far off, so maybe?! I am keeping track, so I will be back to update as I go. Currently, I feel fine taking this, and it never makes me feel nauseous.

It is a 60 capsule (30 day) supply. Easy to pop out blister packs of 10 capsules, 6 blister packs total in a cardboard container. The pills are a typical sized basic soft capsules that could be opened up and added to food or drink. Acquired 08/2020, it has expiry date of 02/2021.

From my knowledge of Ashwagandha, if you have hyperthyroidism, you may want to avoid this herb, where as if you have hypothyroidism (me!) it can be a helpful herb to use.

Suggested daily use: take 2 capsules with a glass of water.

INGREDIENTS 1 CAP 2 CAPS
-Brown Seaweed (Ascophyllum nodosum) extract 100 mg 200 mg
(increase hair mineralisation, which leads to thicker hair)

-Ashwagandha (Withania somnifera) extract 170 mg 340 mg
(improve scalp circulation and strengthen the hair, possibly reverse grays)

-Triphala extract* 170 mg 340 mg
(repairs damaged hair and increases hair volume)
* (Emblica officinalis, Terminalia bellerica, Terminalia chebula, 1:1:1)

-Korean Ginseng (Panax ginseng) extract 20 mg 40 mg
(strengthens the hair follicles with optimum nutrition, thereby reducing hair fall to a large extent and stimulating healthy hair growth)

-Fleeceflower (Fallopia multflora) extract 30 mg 60 mg
(helps stimulate the growth stage in hair follicles)
--------------------------------------------------------------------------

Notes:
--Seanergix 4 New Hair is not effective in cases of Male Pattern Baldness (baldness due to generic reasons).
-- Not recommended for pregnant women.

From their webpage:

The combination creates one of the best and strongest Natural products to prevent hair loss and regrowth hair.
--After 3 weeks of using Seanergix 4 New Hair it will be visible that the hair is in process of reduction in hair falling.
-- After 3 months of using Seanergix 4 New Hair almost 40% of new/regrowth hair will be seen!!!
-- After 6 months of using Seanergix 4 New Hair the reduction in hair loss is almost stopped while the hair growth continues to regrow.

This is one of those things that if you see it working, you will want to continue with it. Upfront expectation to really know if it is working seems to be around 3 months-- which would be true of any product of this nature.

---------------------------------------------------------------------------------------------------
EDIT: Within the one full pack of use (some skipped doses), I can tell there is less hair fall. This makes the first benchmark accurate. \"After 3 weeks of using Seanergix 4 New Hair it will be visible that the hair is in process of reduction in hair falling\". Possible that I was ending a shedding phase, but I have indeed experienced reduced shedding while taking this product.

It is because of this that I decided to KEEP GOING with it. Going forward.. For me to be able to tell the second benchmark has been met, \"After 3 months.. almost 40% of new/regrowth.. will be seen\" I will need to continue to buy this. So I know I will actually need at least 2 more to be able to tell if this second benchmark is accurate. I may be awhile, but I will continue to update. (and of course, if it does actually work, then I will be continuing this for quite some time).',\n", + " 'The \"Drop the Bomb\" BBOSONG Suns stick uses one of THEE best UVA/UVB sunscreen ingredients on the planet: \"Bis-Ethylhexyloxyphenol Methoxyphenyl Triazine\"! Say that 5 times fast. Or once. lol. It is a broad spectrum, highly photo stable, chemical sunscreen. Chemical sunscreens mean that they absorb rays and disperse as heat before they can reach skin and do damage. The SPF rating of 50+ and PA++++ means that it offers the highest amount of protection that a sunscreen can offer.

Korean skin care, particularly sunscreens, can use super effective ingredients that products made in (or for) USA can not have because the governing bodies have not approved it. It is not because they are unsafe, but because there is a significant amount of bureaucracy involved. No new sunscreen ingredients have been approved in the USA in over 15 years, sad since there are so many wonderful innovations in the rest of the world. We lag greatly behind. Fortunately, we can still buy these products.

The other sunscreen used in this product is, Ethylhexyl Methoxycinnamate (Octinoxate)- a less stellar chemical sunscreen that has mixed thoughts on its efficacy, safety, and desirability. It protects only against UVB rays and breaks down when exposed to light (10% per 30-40 minutes). However, when combined with another broad spectrum sunscreen, it compliments it very well.

The third sunscreen component is, Octocrylene. Screens out the UVB and somewhat in the UVA II range. It is quite photostable (loses 10% of SPF protection in 95 mins) and is often used to stabilize other photo-unstable UV-filters (octinoxate) It is also often used to improve the water resistance of the products.

As for all the other ingredients- primarily stabilizers, viscosity controlling ingredients, hardeners-- basically all ingredients that make it a STICK than can glide onto the skin. It is formulated to melt into the skin on contact, and yet absorb thoroughly. Basically, you won\\'t even know it is there.

And like so many other Korean skin care items, there are ingredients that go above and beyond the basic sunscreen-- included are skin loving ingredients (emollients, skin conditioners, soothers) such as Japanese knotweed, water lily, gotu kola (centella asiatica), camellia japonica, Lespedeza Capitata Extract (anti inflammatory), scutellaria (ie scullcap/mint), green tea, licorice, rosemary, chamomile

Has a super mild scent- clean, fresh almost like a deodorant, but subtle.

Happens to be a in a container that reminds me of deodorant. Super small, cute. Stick in a pocket or purse. I happen to love using it on my hands. I am in my 40s, and while I have been using SPF most of my life on my face, I figured it was high time to remember to put some on my hands. I like keeping this in my purse or my car, and applying it when I go to drive. That seems to be the time that my hands are most consistently exposed to the sun. Figure, hands on the steering wheel and in front of a big window. So yeh, this is perfect for that.

I have no problem using this on my face. Doesn\\'t grab skin when used over a moisturizer. If need be can be applied/emulsified in palms then patted on. I prefer it as my \"reapply\" SPF rather than my first application product (I am used to a cream style). When I do apply it to my face, I always run it over my lips. It is very silky, doesnt have a sunscreen flavor or feel, and it is adding much needed hydration and protection from the sun.

Again, I am in my 40s.. clear fair skin but with Rosacea (non acne- just redness and visible veins). Leans dry. Loves Korean skin care.

This is so clear, so clean feeling, and so incredibly light that I wish I could show you how it doesn\\'t even feel like anything is on. Not greasy, not even dewy. My skin feels bare.

If I have any complaints, it is the use of fragrance. While it smells nice and doesn\\'t really linger.. it would not make a top choice for use on my face. I do however like it for everywhere else and rather enjoy the light scent before it dissipates fully.

Even so, it is a really good product, so far. If I experience anything else, I will be back to say so.

For all the other ingredients, the each rate 1-2 (very low in terms of hazard to self or environment) on EWG Skin Deep Database.',\n", + " \"First one I have ever used, so I have nothing to compare it to. When I looked at it, I thought I had been bamboozled as it appears to just be an airy dry foam sponge in a tin can. Maybe that is all it is. So I set out to change eye shadow colors, and was floored by how it thoroughly cleaned my brush. What is this sorcery? I don't use too many colors, and I either change brushes or wipe it on a reusable cotton round to clean off one shadow before moving onto next. My brushes always still have a little color on them (whether it be powder or cream). THIS? This took it all off my brush.

I still stare at my clean brush in wonderment.

Are there better eye shadow switching pans? no idea. I can only tell you that my brushes always come clean, so far.

Also, fits nicely in my make up box!\",\n", + " 'I may be in the minority here, but I rather like this mascara. And yes, it is made in China. Not, \"made for USA but made in China\", but it is a Chinese beauty product. No idea if its been around, how it ranks with beauties on that side of the world. Couldn\\'t tell you the ingredients. Tried translating, but I repeatedly failed. Search engines insisted that I was looking for CPAP not CPCP.

So, I usually end up with more mascara that I DONT like rather than what I DO like. I LIKE THIS.

Why? Because my eyes are super sensitive to make up, and this doesn\\'t bother me. AT ALL. I love mascara, but often find myself needing to wash it off after a couple of hours (if not immediately, depending on the brand). No joke. It sucks. So when I encounter a mascara that..well.. allows me to actually wear it- I add to my list of potential repurchase. I have tried so many over the years. Funny thing, a few on my list happen to be cheap mascara (Essie, Wet-n\\' Wild,), --but not all-- and most mid level priced brands bother me as well as uber expensive \"natural, healthy\" brands. What I have noticed is that the WATERPROOF brands do the best in terms of feeling gentle and non irritating (probably less likely to flake). Next up, is the most recent generation of mascara that includes \"4D silk fiber lashes\", which this is.

The 4D Silk Fiber Mascara is so very different in feel and performance over traditional mascara. It has this interesting ability to coat the lashes- like a black body suit is being painted onto each lash. It easily and instantly really darkens the lashes, and can add volume and length. The formulas tend to be waterproof, and yet somehow wash off much much much easier than typical waterproof formulas. So for me, from application through face washing, the 4 D silk mascara is much easier and gentler to work with.

My lashes do not look like how they have it portrayed in the pics. If you already have long lashes, I imagine this will be extra glamorous on you. For me, with my mediocre lashes that simply need a boost of color to make me happy (and not make me want to claw my eyes out)- this works well on me. I included several pics. 3 with one eye with it on, one eye with it off. Then I followed up with 3 pics of the mascara on both.

It shouldn\\'t matter, but the box is super pretty. I still have it, and I have no use for it, but it is just so pretty to look at. Added a picture of the mascara wand.

If I can glean any further information about this product, I will come back and add to this review.',\n", + " \"Can't go wrong with Cica cream, and at this price it is a bargain.

Cica cream is soothing and hydrating and is especially great if you have easily irritated or sensitive skin. It can really be used by anyone with any type of skin, or skin conditions. It is just a good all around cream. It typically contains centella asiatica, the star of the soothing ingredients. Not sure how much is in this, but it states 50% of the product

It is even nice to use this when you just want to give your skin a break from other products, or if your skin has been stressed (environmentally), or if your skin is reacting to something and you need a soothing cream to get through until your skin settles down.

I usually use it on my face (in winter) or hands all year, but especially lately. While I always wash my hands often, the past few months I have been using commercial anti bacterial soaps which are much more drying than some-- using CICA cream helps keep my hands looking and feeling healthy). SO yeh, I am mostly loving it as a post hand washing cream.

Before this one from Village11Factory, there were two other cica products I have used in my life, both a bit pricier. So I think this is good one to try if you are seeking to try it out, and want a simple but effective skin soothing product but don't want to break the bank. The difference is usually what else is in it and sometimes a little difference in texture.. This one is the lightest of all that I have tried, leans more gel like. It is nice and light- one I think is nice for summer. I think I prefer my slightly heavier, creamier one (But 3x pricier for same amount) for winter use-- when I need the extra support in cold, skin chapping weather. OH yeh, this is good stuff for lips too. It isn't a huge tube, so it could be carried in a coat pocket or purse, no problem.\",\n", + " 'Oops! I didn\\'t realize when I ordered this that it says, \"medium\" in the product description, which is what I assume is the level of tint as this is a tad dark for my very fair skin. I don\\'t see an option for any other tint level, so this might be it. Medium-- which appears rather dark and warm directly out from bottle, BUT after it is applied it seems to just blend in- albeit just a hint of color-- not opaque like a foundation. I am surprised it blended in as much as it does as my skin is quite fair & pink, with cool undertones. Still, I likely won\\'t use this by itself. It blends in, but it gives me a slight tanned look, \"a sun kissed glow\". Tells me that with sweat or uneven application I could have trouble with resulting look. My plan is to mix it in with one of my sunscreens that have a greater white cast..

This is a physical (ie mineral) sunscreen, using zinc oxide. Physical Sunscreens work by sitting on top of the skin to deflect and scatter damaging UV rays away from the skin (whereas chemical sunscreens absorb rays, converts them to heat, then releases). They are often referred to as physical blockers. The benefit of using zinc oxide is its strength in protecting your skin against the sun. It is one of the most effective sun protectors available, blocking out both short and long UVA rays and all UVB rays. Either type is great, and it depends on what works best with your skin.

This product is rated as having a BROAD SPECTRUM sun protection factor of 31 (you want anything over 25). There are some other delicious, skin loving ingredients contained in this product such as shea butter, jojoba, oilve oil, and vitamin e. It comes out thin, and applies smoothly. It provides a light sheen which you may or may not like. Not greasy. It absorbs well. I really like the multi action sunscreens. While I wear sunscreen all year round, and I have elaborate skin care routines.. I tend to keep it super simple in the summer. I tend to forgo my morning skin care ritual for just sunscreen (I figure I will be reapplying often, sweating it off, etc.. so why waste other skin care goodies when I can find a decent SPF product that will also moisturized my skin). So with this having ingredients that are good for my skin and help keep it moisturized, I feel better about keeping it so simple.

Again, I would like it better if the tint was a better match. That is on me that I didn\\'t notice the \"medium\" in the description. And it also says that it gives skin a \"sun kissed glow\". If that is at all appealing to you, then give this a try. If your skin is anything darker or warmer than cool, fair skin.. then give this a try. There is NO WHITE cast, at all. If your skin is real oily, then this may be too much for you.. not sure. It feels goo on my normal to dry skin; seems to absorb. It doesn\\'t feel heavy, and it doesn\\'t feel like... sunscreen. It is light.

My skin: mid 40s, leans dry, semi sensitive, non-acne Rosacea (redness, visible veins), I avoid sun-- I always use SPF all year, and often wear a hat or visor. My favorite skin care is sunscreen. If I use nothing else, it is sunscreen that I keep in my routine. I go through a lot, and try a lot.. if I don\\'t like it for my face & neck, then it gets used on rest of body. This is a new brand for me to try, and so far I like it (even though I have to tone it down by adding it to one of my more white cast sunscreens.. OR go for the sun kissed glow).

I hope this helped . I will be back to update if I learn anything new, or think of anything else.',\n", + " 'I am a big fan of Neogen products, and Korean beauty products in general. I like that the focus tends to be on creating healthy glowing skin through skin loving ingredients and maximizing hydration, which all skin types need. I find these Neogen Real Charcoal Pads to be super gentle, non irritating, lightly hydrating, skin brightening, deep cleaning of pores and other yucks on skin. Skin never ever tight, never irritated-- and I have non acne ROSACEA (flushing, telangiectasias/veins).

I hadn\\'t used the charcoal pads before, so I was excited to try them out. There are 60 pads in a tub with twist off lid. One side of the pad is quilted and you can clearly see the charcoal coloring. The other side is smooth. The pads are quite damp, and there is plenty of product on them to take care of face and neck, or to use as a targeted \"sheet mask\". Avoid eye area.

DIRECTIONS: AFTER washing, swipe the quilted side over skin. Then use smooth side to pick up traces of impurities. Pat in remaining essence.

When I swipe the quilted side over my skin, I like to go slow with gentle pressure. I allow the product to sit for a moment before flipping the pad over to the smooth side (more white than gray) and wipe my face. One side applies the product, the other helps to lift up what is left behind- or brought to surface as it is meant to draw out impurities and wastes. I noticed that the pad was turning tan/brownish leading me to believe that these pads were indeed doing a good job of breaking down excess junk on my face (despite a good cleansing) and leaving my skin feeling supple and clean. I followed the directions that state to pat in any excess product. I wasn\\'t sure whether to follow up with my hydrating toners, or skip to my Hyaluronic Acid (HA). Since skin needs moisture to make HA most effective, I patted on one layer of hydrating toner, a layer of HA, followed by a moisturizer to help lock in the hydration. I think this charcoal pad is gentle enough to use daily, if need be. However, I have been using it 2-3x a week. You will have to experiment to see what is best for you. My 40 something rosacea skin is sensitive, leans dry, and loves hydration. My skin can use an occasional boost in really purifying my pores and such. I am really liking this product so far. It just feels so gentle on my skin!

Benefits, and a little more info:

--Charcoal powder and peeling essence ingredient- Hydroxycinnamic Acid- provide double synergy effect for absorbing sebum and removing dead skin cells. The charcoal powder delivers gentle yet effective adsorption benefit to draw impurities, while hypoallergenic peeling essence (Hydroxycinnamic Acid) provides manual exfoliation combined with chemical peeling effect.

--Manual exfoliation + chemical peeling effect.
--With two sides including Charcoal pad that cleanses the skin and embossing pad that softly purifies the skin.

--Pore clarifying: Formulated with natural Peat water and Charcoal powder(310 ppm), these help to draw deep-seated sebum, whiteheads, dead skin cells, and other impurities out of pores for smoother and clearer skin.

--Gentle Peeling: NEOGEN PHAโ„ข removes dead skin cells and impurities without irritation or discomfort while leaving the skin radiantly hydrated and smooth. Softly cleanses skin, non irritating.

--Skin soothing: TECAโ„ข formula (Titrated Extract of Centella Asiatica) delivers a soothing benefit to skin; helps create bright skin. Centella Asiatica has potent antioxidant properties, rich source of amino acids, and there\\'s additional research showing that it\\'s a good hydrating ingredient to soothe upset or compromised skin.

INGREDIENTS:
Water, Butylene Glycol, Glycerin, Dipropylene Glycol, 1,2-Hexanediol, Betaine, Panthenol, Charcoal Powder(310ppm), Peat Water, Asiaticoside, Madecassic Acid, Asiatic Acid, Acacia Senegal Gum, Cetearyl Olivate, Sorbitan Olivate, Allantoin, Gluconolactone, Citrus Aurantium Bergamia (Bergamot) Fruit Oil, Glyceryl Caprylate, Tromethamine, Ethylhexylglycerin, Acrylates/C10-30 Alkyl Acrylate Crosspolymer, Xanthan Gum, Propanediol, Citric Acid, Hydroxypropyl Methylcellulose, Alcohol, Rutin, Hydroxycinnamic Acid, Potassium Sorbate, Disodium EDTA',\n", + " 'This is my second scrub with this company. The first was great, but I find that the fragrance is too much for me with this Honey one. These products do contain \"parfum\" as an added ingredient, but it is last on the list. I have included a picture of the ingredients as I do not see the list anywhere else. My other salt scrub by this company-bloodorange, and that scent is wonderful and fresh, in bottle, in shower, and on skin after (very light). This one is just heavy, rather perfume like. I have noticed some shea containing products have that, but the other one that I do like has shea as well but isn\\'t cloying. So I don\\'t know. I\\'m afraid it might trigger a headache for me. I may have to have someone else in the household finish it off. Love the other one I mentioned, though!

As for how it works- no problem. A thick frosting like creamy texture with a hint of grit. It does a nice job cleaning, polishing, and leaving the skin feel smooth and moisturized. It is a gentle scrub- very gentle. Definitely softens skin. I scoop out a generous 1/8-1/4 cup amount to use on my body. With that amount, I expect several uses from this squat container. I particularly like this one for my legs and feet as they are the most neglected in terms of skin care.

I really do like Natural Soultion salt scrubs, and it appears that there are 4 kinds. This one based solely on the fragrance is a miss for me, but another one happened to be a hit for me, which I will continue to use as needed.

EDIT: While a whiff from the container is too strong for me, the actual aroma in the shower continues to be pretty tame. It dawned on me to smell my skin after showering (something I didn\\'t do with prior showers prior to initial review), and my skin doesn\\'t have that strong smell that I note from the container. It smells pleasant and light, and I wanted to come back to say so.SO I just wanted to say that I haven\\'t had a headache, and I don\\'t actually smell like the scent from the container- I was concerned I would have that perfume smell. It isn\\'t there, thankfully.

I\\'d boost it to a 5 rating, but the product descriptions says, \"No Artificial Fragrances Or Perfumes\", and \"parfum\" is on ingredient list- and doesn\\'t say where that is derived from.',\n", + " \"These are great. I love the look- nice colors and design. Just the right size for travel, and are TSA approved sizes. Easy to use, easy to clean, good seals. I don't travel much but my husband does often for work- sometimes by plane often by car. Either way, he has to pack toiletries. With six squeeze bottles and 3 tubs, he has some and I have kept a few for my own use. The fact that they are BPA free food grade silicone opens up some options for use of these bottles- whether traveling or for out and about (work lunches!).\",\n", + " 'WOW!! These are good. They are very similar in style to all the other dermaplaning razors out there, but they are longer than any I have used. The blade is just a hair under 2\". Pun intended. One of the popular blades among beauty conscious people (pictured) is around 1.5\". Many are 1\" or less. SO, keep this in mind for where you want to use this and if you are comfortable with that length of blade. Otherwise it is all very similar.

I like that this 5 pack is contained within a box. Many are on a flat piece of cardboard with molded plastic around them. Makes it too easy to lose one, misplace one.. they just fall out of package when opened. This box will nicely store the remainder. I won\\'t lose these among my other beauty goodies.

I have no idea what it says on the box. The sticker on the box says Made in China. The box says, Made in Japan. I can\\'t read anything else.

Handle is short- I think adds to precision of use. The longer blade makes it harder to get the eyebrow area. For that, I would go with a smaller, angled razor. For larger areas of face (or other body areas), this large blade is nice. As with any blade, BE CAREFUL. And don\\'t over use it- a dull blade can be as dangerous and damaging as a sharp blade.

The blade is indeed sharp. I usually use a regular razor (like for shaving legs) to shave my face. I have pale skin and dark hair, so I have always preferred to just shave off my hair. No, it doesn\\'t grow back thicker or darker. But it sure makes the face nice and smooth- great for make up looking good, for skin care setting in nicely, for exfoliation- for overall health of skin. A leg razor is fine, less likely to cut.. but a straight razor provides an extra close shave (if careful). I love these for taking care of upper lip area, and for eyebrow area.. but is taking some getting used to since it is a longer blade than others I use.',\n", + " 'So much better results than a manual toothbrush. So much better than a battery operated toothbrush. This really does a good job getting the teeth and gum area clean. Definitely helps in keeping mouth healthy. I have a used a few brands and they all do a good job- some last longer than others, some have replacement heads that can be purchased as generic, some dont. I usually purchased the name brand replacements. Anyway, I was always happy with my toothbrush.',\n", + " 'I use a larger plug in water flosser unit in my full bathroom (on upper level of house) which has a large capacity water reservoir. I typically take my time and use it at night before bed. However, I wanted a unit on my main floor bathroom for quick use during the day without having to go back upstairs, or for use if I am going to be gone all day and want to take it with me. Therefor I have been keen on getting a portable chargeable flosser. That, and my first floor bathroom is super tiny with nowhere to put a typical flossing unit nor anywhere to plug it in. This is perfect for me!

Nice unit, right out of the box. It is attractive, feels comfortable in the hand, as is easy to get it going. While it comes with instructions, it is easy to figure out- very intuitive. USB cord is good length. The port that plugs into the unit has a pop-in cover (\"anti-fouling rubber stopper\"). It doesn\\'t come attached, and I wish it did since I\\'d rather not have that area exposed to water. I sense that I will lose that cap soon enough, or just forget to use it. We\\'ll see.

The unit comes with four attachments, all for doing different jobs- so unless someone has a need for this unit and for an attachment for something different than what you need, I would say this is for solo use. Good sized water reservoir, too.

Unlike my main unit, this one has a fairly straight nozzle in comparison. This makes it a challenge to get behind the rear most molars. If the nozzles were a little longer, with slightly more curve than it has, I would consider this a perfect product.',\n", + " 'I waited a little while after trying out this product to write a review. I was super curious about it, and I was hoping that it was something amazing that I may have overlooked in my skin care routine. I read that it is way more effective than an eyebrow razor. Then I tried it, and it made me laugh. It is not better. I don\\'t want to sound cynical, but I really don\\'t want you to spend money where you don\\'t have to. See, Do It Yourself/DIY deplaning is pretty much shaving. Don\\'t let this more expensive \"deplaning tools\" state otherwise. I would either buy any regular shaver of your choice, and/or use one of the smaller eyebrow shaver tools. Check out Youtube and see all the people using the latter for this purpose. This is NOT salon level. Putting it in a pretty pink box and seeing single blades in an awkward razor handle (sorry, \"WAND\") does not justify expense. Even if it were as cheap as a typical razor, or eyebrow/facial razor, I still would not recommend, which I will get to.

If you take a look on Amazon, more and more of the eyebrow/facial razors are coming out, with longer lengths, and with the hot word, \"deplaning\" in the description. Despite the product description/cautionary tale- eyebrow razors are sharp enough, as well as regular razors. Seriously, if you are looking to remove thicker hair or even peach fuzz, one of these cheaper tools will work. This is trying to fit that niche, but with a fancier presentation. Don\\'t fall for it. Schick has regular razors and the small eyebrow/facial razors that will do the job.

Why do I say all this? because I shave EVERY day. I use a regular razor (I think 3 blade) on the large parts of my face, and the smaller eyebrow/facial razor (single blade) for smaller areas (thought these areas only need to be attended to once in awhile). I am a female in my 40s and I have been shaving since I was in my teens. I have dark hair and very light skin, with a propensity toward excess hair all over, so any hair on my face stands out. I never cared for that (shocker), and NO, shaving never ever creates more hair, or thicker, or whatever. What shaving (or call it \"deplaning\") does do is clean up the face and exfoliate. Shaving isn\\'t just for guys!

Anyway, I used this on one side of my face, and use my other typical tools on the other. I preferred outcome with my typical tools. I tried it over the course of a few days, so I could give it a chance and determine if I learned anything new. But I kept coming back with same result- this is no better, and even less effective than my regular razor and/or little eyebrow facial razor.

When I tried this product, I was thinking that maybe I would get an even closer shave. Nope, not even close. I tried it according to the meager directions- use on a dry face. Not impressed. Thinking maybe I could do better with a damp face, I tried that- definitely not. I pulled skin taut, I made sure product was pressed firmly but gently, I tried short strokes, I tried long strokes.. I worked the angle of the razor as recommended, and just found it hindered my sight, and it was hard to tell if I was getting anywhere with it. I went back and tried to research the product, or similar products, I tried to find videos- just nothing that made me think I was at all using it wrong. I am experienced with facial hair removal, and this is not what I will be using.

One thing I do kinda like: I like that the handle is trying to make people use it at the correct angle- it takes a little getting used to. There is a tiny bit more fineness required with the small single razor eyebrow/facial razors, but I have never cut myself with one. I did nick myself with this. So maybe the guiding design isn\\'t great, after all?

I want to clarify: General information on deplaning says not to use products for a couple of days and to only do this once a month or so. That is really just for professional level deplaning. If you are doing this at home, with what amounts to a regular razor, (no matter the size, or how it is packaged), once can and should use their products as usual, and shaving can be done daily. If you do not have much hair to remove, then just 1-2x a week should suffice. If you are a hairy beast like me, who could easily shave 1-2 times a day, then know that the degree of exfoliation provided in this manner does not require refraining from product use. Though, that is all dependent upon how your individual skin reacts. Now, if you were getting this professionally done (the tools are different, and does a thorough job), then by all means follow directions of your technician.

What\\'s in box: 2 handles, with two razors (ie, \"deplaning blade\") in each handle (ie; \"wand\"). A little brush to clean out hair that will build up. Not extra razors. Not protective cover to keep them sharp. I don\\'t expect them to last long- it is just a single razor, nothing special. The \"wands\" do not appear able to have the razor swapped out. Instructions are same as the \"instructions for use\" listed in this product page. Basically a printed version.

Hope this helped. Again, I don\\'t like to be so negative about a product, but this is one that I do not find more effective than what it is trying to replace.',\n", + " \"It doesn't perfectly straighten the hair, but it definitely smooths it out, getting it pretty close to straight. The crush style straightener is pretty easy to use. It will take a little getting used to over using a flat plate straightener. I was concerned that I wouldn't be able to use it on my long, thick, wavy hair.. but I had no trouble with it. My first time using it was on not freshly washed hair- maybe a day or two after last shampoo. I used a little thermal protector, and then started swiping the brush through my hair. It took longer than using a flat plate to get hair smoothed out, but I do like the natural looking results. I like the ability to use a fine water mist- this helps to smooth out the hair.\",\n", + " \"Jade roller and jade scraper comes in pleasant looking box with a small bag to store these items in. It would make for a nice gift. Product claims to be made of real jade, which I looked for in making my decision.

The jade roller feels good on the face, especially when first being used due to the coolness of the stone. I wouldn't normally buy something like this, but I already massage my face a little every day (fluid build up), so I thought this would be an interesting way to change things up.

Again, I love the feel of the cool stone rolling across my face. I have rosacea and it just feels so comforting on my reddened skin. I haven't been real consistent with its use so I can not attest to how effective it is in terms of benefits to the skin. It does provide a gentle massage, which is good for draining lymph nodes and helping to reduce swelling. I am using it before I put on moisturizers, etc, as per recommendation on instructions. It says using this before hand will help the products work better. In my 40s with barely emerging fine lines, I am all for doing what I can to keep those at bay.

As I learn anything new, I will add to my review.\",\n", + " 'Works easily and well.',\n", + " 'Really cute wig that looks natural on. Loved it!',\n", + " 'I do my facials at home to save money and I love this. It is so relaxing to use. I love how it glides over your face and gives you a mini massage. All in all I am really pleased and it is quite beautiful to boot!',\n", + " 'I have a huge claw foot soaking tub and the back of it kills my neck. This was the perfect solution. Now I can lay in there and relax without my neck hurting. Love it! Shipping was fast!',\n", + " \"110% recommend! Nothing curls my hair ever BUT bed head curlers! And it stays for days. The pics are from yesturday curls I didn't do anything but wake up and toss it in a pony tail. Do yourself a huge favor and get it!!!!\",\n", + " 'I bought these for my 3 year old daughter who is moon obsessed. Sheโ€™s picked them out from the multiple choices on amazon. Weโ€™re on day 7 and itโ€™s still on, only worn off about 1/2 way. She loves them, and it makes her very happy. Would buy again!',\n", + " \"I love the body wash! It has an amazing smell. The lotion does not smell quite as good but it's not bad. It is a light lotion.\",\n", + " 'I love the scent that leaves on my hair!! And my hair has never looked better! Will be buying more!! Thank you!!',\n", + " 'I like the variety of colors it came with. They were not as tight as most head bands are which was great. So far they have held up well and have not come undone.',\n", + " 'First time using a gel UV light and I am surprised at how easy it was to use. It comes with 4 different settings and definitely made things easier & quick way to get nails done.',\n", + " 'It went on smoothly and was precise. I did have to re apply. It is similar to the NYX eye liner but applies better. But by the end of the day it was faded.',\n", + " \"The nails did not stick to my daughter's nails.\",\n", + " \"I like to hear hair I just don't like the term dreadlocks because i do not dread my hair i love my hair i. Thank you. Brother Oran Z\",\n", + " \"[[VIDEOID:50c6456a14894703519e5e34115f6021]] I really like Willie Morrows products and this comb is excellent. I love to use this type of comb when I'm doing relaxers or Jerry curls. The loop is good for taking a section of the hair when it's in a base. The back of the Cove is good to smooth out the back of the head and the sides. I recommend this comb. I think you'd get a better deal when you buy the three black ones because when you buy this one you pay half the amount of the comb to ship which is not hip. Thank you for looking at my review and God bless you. May the rest of your life be the best of your life. Baba Oran Z\",\n", + " '[[VIDEOID:7cfc995b010d23bc7176b91f843fecfa]] Hotep and party on brothers and sisters and thank you for looking at my review of the HMPRT 80s 90s Costume, A Black Mullet Rocker Wig and Wig Cap, Black T-Shirt, Wayneโ€™s World Baseball Cap, and Inflatable Guitar. What I like about this set it\\'s a spoof of Wayne\\'s World and it comes with a Wayne\\'s World cap, a wig, T shirt and an inflatable guitar. The inflatable guitar gives a whole new meaning to the term air guitar. With this you can play Bohemian Rhapsody! โ€œNOTโ€ Long live, Queen.
โ€œWayne\\'s World\" was originally a recurring sketch from the NBC television series Saturday Night Live. It evolved from a segment titled \"Wayne\\'s Power Minute\" (1987) on the CBC Television series It\\'s Only Rock & Roll, as the main character first appeared in that show. A prototype of the Wayne character had appeared several years prior on CITY-TV in Toronto\\'s overnight show City Limits. The Saturday Night Live sketch spawned a hit 1992 film, its 1993 sequel, and several catchphrases which have since entered the pop-culture lexicon. The sketch centered on a local public-access television program in Aurora, Illinois, hosted by Wayne Campbell (Mike Myers, the same actor from \"Wayne\\'s Power Minute\"), an enthusiastic and sardonic long-haired metalhead, and his timid and sometimes high-strung, yet equally metal-loving sidekick and best friend, Garth Algar (Dana Carvey). Wayne lives with his parents and broadcasts his show \"live\" from the basement of their house every Friday evening at 10:30. The first \"Wayne\\'s World\" sketch appeared in the 13th Saturday Night Live episode of the 1988/1989 season. The only thing I didn\\'t like about the Cap is that it clearly looks like a woven Cap on the ad, but the Cap that I was sent is definitely a screen print which I guess is, OK? โ€ NOTโ€. I recommend my friend. Party on brothers and sisters and thank you for looking at my review. I hope it is helpful for you. If so, you can check the helpful box below, it will help me review some More. God bless you. May the rest of your life be the best of your life. O DEE thank you',\n", + " \"[[VIDEOID:2a3b24d571a05f44cc8ace5cc8909f81]] Hotep brothers and sisters and thank you for looking at my review of the spinner or shaker, good this is a good thing for mixing if you're a maker. I like the fact that they come with interchangeable sizes to use your spin. If you can't put in from the bottom you can put at the top my friend.

I recommend my friend. Thank you for looking my review. I hope it is helpful for you. If so, you can check the helpful box below, it will help me review some More. God bless you. May the rest of your life be the best of your life. O DEE thank you\",\n", + " 'You can change the blades and will Bill. It comes with two extra blades to keep your dealing in spades. I recommend my friend shave it close now and then. Thank you. God bless you. May the rest of your life be the best of your life. OZ',\n", + " 'I like the fact that this girl has shoulders and can set on its own. I like to enhance these Gloria heads with eyelashes and eyebrows to give him more of the pop you need in your shop. I recommend my friend. Thank you. God bless you. May the rest of your life be the best of your life. OZ',\n", + " 'Keeping your tongue clean makes your food taste better. Having a clean tongue is healthier for you. I like the fact that this chunky cleaner has his own case to hide its demeanor. I recommend my friend keep your tongue clean again. Thank you. God bless you. May the rest of your life be the best of your life. OZ',\n", + " 'I hate the term dreadlock because I do not dread my hair. I love my hair, the term dreadlock was started by the British who dreaded seeing the Jamaicans the ones they call maroons, come down the hill when they were trying to go up the hill to get them. This is a beautiful set of decorations to go on your lovelocks and some of them really rock. I recommend my friend. Thank you. God bless you and may the rest of your life be the best of your life. OZ',\n", + " \"Good for a minute but then you know it kind of didn't even do my second half mustache. Maybe it's a good for eyebrows but I can't recommend my friend, not for mustaches anyway from my end. God bless thank you. May the rest of your life be the Best of your life. OZ\",\n", + " '40 lashes. I mean 40 pair of eyelashes is a lot of lashes. And they are reusable. I like to use them on my Gloria Dolls heads, to make them look better. I recommend my friend. Thank you. God bless you and may the rest of your life be the best of your life. OZ',\n", + " 'With this kit you get more than just face paint painting cakes, you also get 3 professional brushes. I like the fact that each one of the cakes has three colors in it. The one drawback I find with this kit is that the three colors in each cake can sometimes affects you do not want, be careful not to get a color you do not want while trying to get one color out of the cakes that have three colors in it. Thank you, God bless, you and may the rest of your life be the best your life. OZ',\n", + " 'There is a difference between gel nails and Poly gel nails. This is a nice set of Poly gel nails. This is an excellent set for extensions. I will definitely use this in my OZ fantasy nail summer addition. Thank you for reading my review. God bless you. May the rest of your life be the best of your life. OZ',\n", + " 'Heart to heart from finish to start. These little dishes are quite small but that is what you need to do certain jobs. I use one of these hearts for my martemper and the other jar for my brush cleaner. I recommend it. Thank you for reading my review I hope it was beneficial for you. May God bless you. May the rest of your life be the best of your life. OZ',\n", + " 'The thing I like about this set of tips is the fact that you can change them to look like any of the common fingernails or you can make your own nail your own design. They seem to work good with both powder and Gel, what the. Thank you for reading my review. I hope it is beneficial for you. May God bless you and yours. May the rest of your life, be the best of your life. OZ',\n", + " 'This is like a vacuum cleaner for your face. It sucks the impurities out of your pores, who could want more. Thank you for reading my review I hope it was helpful and entertaining for you. God bless you and yours, have a good day and may the rest of your life be the best of your life. OZ',\n", + " 'Afro Headband Wigs for Black Women Synthetic Head Wrap Wig Afro Curly Wigs Turban Wigs with Drawstring 2 In 1 Natural. Fun to wear and headband very Afrocentric. This would be nice for quick change artists because all you must do is put it on your head and with the headband it looks like you have a natural hairline. OZ',\n", + " 'Face and Body Paint Kit By Color Technik 24 Professional Oil Based Flash Colors, 2 Sets of 12 Color Palettes, 6 paint brushes is a fun to do thang to do. You see all these TV shows these days with people painting their face, painting their body, you might just want to try it yourself and this is the perfect opportunity to do it, with this set of face painting paints. You can achieve many colors and effects with this set. What the heck, I might just wanna go green for a day, what do you say? OZ',\n", + " \"Perfect for those hard to get spots, and for those who hate flossing, like me. I don't know why, but I rather pick at my teeth with these tools than with floss. I'm flossphobic! LOL! These tools are super useful, and when it's time to replace them, I won't throw them out because they happen to be useful for sculpting miniature clay too. 5-Stars!\",\n", + " 'I really needed this for my boys, I cut their hair and they always have hair all through their clothes and even though I tell them to shake there shirts right there when they stand up, there is always a trail of hair going down the hall to the bathroom. This is so nice, the neck is stretchy and fits different sizes of necks, easy to clasp shut and open. I only wish the back was longer like the front but I had no problem with keeping hair off them. It was really nice to only have to clean up in one small area.',\n", + " \"I watch a boy and take him to the park, his sunscreen always leaves white smears on and in my new black car, this sun lotion is clear so that won't happen anymore and it's 50 SPF so he is well protected. It smells great too. yum.\",\n", + " \"feels nice, weightless. I haven't been using very long so can't tell you anything about helping wrinkles but it doesn't break out my skin like a lot of creamers do.\",\n", + " \"love the wag, very comfortable, fun to go out in. My head doesn't get sweaty.\",\n", + " \"I just want to keep touching it, it's so soft. I love the color, so fun to wear. My head didn't get too hot while wearing but I do have short hair that I don't have to pin up.\",\n", + " 'Took awhile to receive them but work like a charm',\n", + " 'Worked amazing on ALL my brushes! All my brushes look like they did when they were brand new! Amazing product and would recommend to everyone!',\n", + " 'These Braided Hair Clips are nice. I used them in my own hair, and I did have a bit of difficulty in the beginning. I practiced on a mannequinโ€™s hair and was able to use them easily.

The pack comes with 4 hair clips. The clips have one big clip on the bottom and three smaller clips on the top. The small clips have little crystals in a flower shape. Each clip has different color combinations for the crystals. Each clip has a spring mechanism for the opening.

I will be recommending these Braided Hair Clips to family and friends.',\n", + " \"This Argan-Infused Round Brush is nice. I used it while drying my hair and I was happy with the results. The bristles felt a little sharp since I have been using a different type of brush but not so sharp, that I couldn't use it.

The box comes with a brush. This brush is round and has nylon bristles. The barrel of the brush is open allowing air from the blow dryer to pass through. Instructions are on the box.

I will be recommending this Argan-Infused Round Brush to family and friends.\",\n", + " 'This bag Makeup Sponge Beauty Blender is nice. I tried out a few of them and I am happy with them. I think my favorite is the little wedges. I find them helpful for getting around the eyes, nose, and mouth than with most makeup sponges.

The bag comes filled with sponges. There are diamond-shaped sponges, wedge-shaped sponges, rectangle-shaped sponges, and round sponges. The thicker ones are pink, and the thinner ones are yellow. Instructions were not included in the bag.

I will be recommending this bag of Makeup Sponge Beauty Blender to family and friends.',\n", + " 'This Morovan Gel Nail Polish Remover is great. I used it to remove my Christmas gel nail polish. I was surprised at well it worked.

The box comes with a 16.9 fluid ounce bottle of gel nail polish remover and a pump bottle. It also comes with a pack of cotton pads and a pack of nail clips. Also included is a file and cuticle pusher. Instructions are included.

I will be recommending this Morovan Gel Nail Polish Remover to family and friends.',\n", + " 'This Acrylic Nail Brush Set would have been nice, but my fine liners are messed up. I have tried to fix them and so far, nothing works. Not impressed.

The tube comes with 8 brushes in different sizes and brush types. These brushes are used to decorate the nail when the brushes are in good shape. There are no instructions included.

I will not be recommending this Acrylic Nail Brush Set to family and friends.',\n", + " 'These Nail Art Brushes are pretty. I love the shape of the handle and the color. I like the 6mm size best.

The box comes with 6 brushes. Each brush is a different size from 6mm to 11mm. There are no instructions for cleaning included.

I will be recommending these Nail Art Brushes to family and friends.',\n", + " 'This RSTYLE UV Gel Nail Polish Set is beautiful. I love the red and will be wearing it very soon. The white I will be wearing but I will be using nail art paint with it.

The box comes with 4 bottles of gel polish. Each bottle has the color of the polish on the top of the cap. There are instructions for how to apply the gel polish. It does not include a UV lamp, base coat, or top coat.

I will be recommending this RSTYLE UV Gel Nail Polish Set to family and friends.',\n", + " \"This Janier Coffin Nail Tips Nail Glue Kit is nice. I love that I don't have to put on a base coat first. This nail glue is a base coat and glue on in one bottle. I also love the gemstones.

This kit contains a box of soft gel tips. The box has sections inside dividing the different size nails. There is also a number on the tip of each nail. Also included in the kit is a pair of edge cutters, a file, a pack of gemstones, a small UV lamp with a USB cord, a bottle of top coat, and 2 bottles of glue.

I will be recommending this Janier Coffin Nail Tips Nail Glue Kit to family and friends.\",\n", + " \"This Makartt Nail Decoration Set is gorgeous. The only thing I don't like is the static in the containers. The pieces attach to the top of the container until you open them and then little pieces go everywhere.

The kit comes with a plastic tray with 12 small containers inside. Each container opens and closes with a screw-top lid. Be sure to set the container in something before opening it as the contents will go everywhere, especially the small things. The containers have beads, gemstones, and charms. There are also 3 small sheets of stickers included with the kit.

I will be recommending this Makartt Nail Decoration Set to family and friends.\",\n", + " 'This WALRUS OIL seems to work pretty well. I have two tattoos that were looking a little dry. I put some oil on them and they did brighten up some. I will continue to use this to see if it improves more over time.

The pack comes with one 2 ounce tin of vegan oil. It does have a slight scent but it is not overpowering at all. This product is for new and old ink.

I will be recommending this WALRUS OIL to family and friends.',\n", + " \"This Simple Pleasures Kit is cute. I think I might have clicked on the wrong thing. This looks like a child's set.

The kit includes two separate sets. One has a separator and 6 small bottles of polish. The other set has 4 larger bottles of the colors in the first set. This one has nail stickers included. These polishes are water-based and kid-friendly.

I will not be recommending this Simple Pleasures Kit to family and friends.\",\n", + " \"This Mini Nail Dust Collector is nice. I would have loved to have instructions included with the collector. I did go on the purchase page to see that I needed 2AA batteries. There is one part that I still don't know what it is for. I did a test and it did work and I am happy with that but instructions would have saved time.

The box comes with the collector. It has two little tools include. On small brush and I don't know what the other thing is.

I will be recommending this Mini Nail Dust Collector to family and friends.\",\n", + " 'These Crystal Glass Dappen Dishes are so cute. I got them for slip solution. I may also use one for polish remover.

The bag comes with two cute dishes. Each dish is clear and just deep enough for slip solution or polish remover. The plastic bag reseals so the dishes could be stored if needed.

I will be recommending these Crystal Glass Dappen Dishes to family and friends.',\n", + " \"This Havtyyise-3 set is nice. I really like the hand mitt. The holes on each side are better than the ones with no holes. This made it easier to get the soap on and keep the mitt on all at the same time.

The set comes with a mitt, a handled back scrubber, and a pouf ball. The mitt is the best in the back and the back scrubber comes in second. I do not like the way the pouf ball is made and I don't see it lasting very long. It just flattens out because it is poorly made.

I will be recommending this Havtyyise-3 set to family and friends but I will let everybody know about the pouf ball.\",\n", + " \"This JODK Heatless Curling Rod Headband is so cute. I loved how it looked when my hair was in it. I waited 4 hours and my hair still wasn't dry so it didn't curl. I will be trying it again.

The box comes with a hair curler and clips. It also comes with 4 scrunchies, 2 large and 2 small. There is also a beautiful, drawstring bag to store everything and instructions.

I will be recommending this JODK Heatless Curling Rod Headband to family and friends because it is so cute.\",\n", + " \"This Women Ultra Smooth Razor works well. It glides smoothly and cuts great. My problem is I don't see a place to buy replacement heads only razor blades. Instructions say to replace the blade every two months.

The pack comes with a base, handle, and two razor heads. The razor heads have covers on them and they are magnetic. There are instructions but it does not say where you can buy replacement heads.

I will not be recommending this Women Ultra Smooth Razor to family and friends.\",\n", + " 'These HH&LL 4pcs Large Hair Claw Clips work great. My hair is not thick but these clips stay in my hair. I am impressed at how well they work.

The pack comes with 4 large clips. The teeth of the clips go inside each other enough to hold the hair. The colors in my box are white, pink, black, and brown.

I will be recommending these HH&LL 4pcs Large Hair Claw Clips to family and friends.',\n", + " \"This Silk Exfoliating Mitt is soft. I used the mitt on my face. I can not tell any difference between this mitt and any other mitts except that it is soft. No difference in the skin.

The mitt fits the hand for cleaning. The resealable package comes with a mitt. It says 100% silk but I'm not sure I would agree with that.

I will not be recommending this Silk Exfoliating Mitt to family and friends.\",\n", + " 'This NULASTIN - Gentle Exfoliating Cleanser works great. I put it on my palms and then put it on my face in a circular motion. It felt great.

The cleanser has a pleasant smell. It has an exfoliating cleanser and a moisturizer. It makes the face fill great.

I will be recommending this NULASTIN - Gentle Exfoliating Cleanser to family and friends.',\n", + " 'This DARKLATER Tongue Scraper is not worth the time. I used both of the scrapers. I could not tell a difference after using them. I am not sure if I was doing it right but it did not come with instructions.

The set comes with two scrapers in a metal container. Both of the scrapers are metal with a copper look. I did go to the Amazon website to see if there were instructions. What I found was a section for Videos. Under that was this: Help others learn more about this product by uploading a video! Then a button that says: \"Upload video\". I will not upload a video just to help others learn about the product when I don\\'t even know about the product!

I will NOT be recommending this DARKLATER Tongue Scraper to family and friends.',\n", + " \"This Pre-stretched Braiding Hair Purple is pretty. I got it to put in my mannequin's hair. I make handmade scarves, hats, and other things that would look great with this hair. I was surprised at the amount of hair I got.

This hair is beautiful. There is 8 individually packaged purple hair. Included with the package is a latch hook but not beads to attach the hair.

I will be recommending this Pre-stretched Braiding Hair Purple to family and friends.\",\n", + " \"This Jopuzia Natural Jade Roller is beautiful. The roller doesn't appear to do anything for my facial skin. I love the jade that is why I gave it a two-star rating not because it worked for the skin.

This set comes with a large almost heart-shaped piece of jade. There is a roller with three pieces of jade. I will be using this jade in something else.

I will not be recommending this Jopuzia Natural Jade Roller to family and friends.\",\n", + " 'These Daletu Nail Tip Clips work great. I put on the nail and then clipped it to my finger. It helped the nail stay in place while it dried. I think they will be good for other crafty things too.

The clips are clear and they are not too tight on the fingers. They come individually packaged. Because they are clear it helps to get the clip in the correct place on the nail.

I will be recommending these Daletu Nail Tip Clips to family and friends.',\n", + " 'This HEXZE-emoji the iconic brand Moisturizing Lip gloss is bright red. I have fair skin so this \"gloss\" made me look like a corpse. It is also supposed to be a moisturizer but it made my lips crack and peel. Not happy with this at all.

The lip \"gloss\" comes in a little tube and you brush on the color. If you have a different skin type than mine you might like it but it did chap my lips. I would think twice before getting this product.

I will not be recommending this HEXZE-emoji the iconic brand Moisturizing Lip gloss to family and friends.',\n", + " 'Colors are beautiful!',\n", + " 'Beautiful, thank you!',\n", + " 'Loved that this came in a gift basket, very cute! These all smelled great and were a lot of fun to use in the bath!',\n", + " 'Works great and very easy to use! A great kit for people just starting out with nails. I also use it for various other things that I need to sand down a bit around the house, it works great on multiple things! Definitely recommend!',\n", + " 'I used this when I had a cold and it was really relaxing and soothing. Helped my sinuses quite a bit. Definitely recommend this!',\n", + " \"This cleanser works great. It starts off kind of like shaving gel and then like shaving gel you can form a foam by rubbing it on your face. Leaves my face feeling very clean but doesn't dry my skin out which is a bonus! Definitely recommend this stuff!\",\n", + " \"Great set that gives you smooth skin for your foundation makeup. Too heavily scented for my liking so I took a star off for that. This isn't the best primer I've tried in this price range but it works. A decent quality product that doesn't irritate my skin.\",\n", + " \"Beautiful! I'm so excited to wear it for my wedding.\",\n", + " \"I hate greasy moisturizing creams that sit on the surface of my skin and clog up my pores, which, I'm afraid, is most of the moisturizers out there, but I do need something for my aging face in our dry, high altitude home, especially in winter. This serum is easy to use and absorbs quickly. You apply it morning and evening with or without other creams. It won't make deep wrinkles disappear, but if you use it consistently, you will probably notice a positive difference in your skin, I know I have.\",\n", + " 'Christmas gift that was loved.',\n", + " 'Great price for the quantity. They work great!',\n", + " 'This bag is way smaller than I expected but still useful for small items such as tampons or toothpaste. Truthfully, I will probably just trash it or give it to my 8 year old after my vacation. I had originally rated 1 star but upped it to 3 because the seller was very attentive. My issue was addressed promptly.',\n", + " 'These are pretty colors but even with a base, filing all along nails and a top coat, they peel right off.',\n", + " \"First, these are so super cute and I loved them when I first got them. However, the love quickly faded as I started using them. While they totally work and hold your hair up, they break very easily and I have very fine thin hair. So, if they break so easily with my fine hair, then people with thicker hair, well good luck. These are better for looks than actually using them to hold your hair, and that's not what I was looking for. So, while these are super stinking cute, they don't really work holding your hair without breaking.\",\n", + " \"Cute nails but some of the sayings just don't go together and would have been better just plain.\",\n", + " 'These nails are super cute and wear beautifully. Love them.',\n", + " \"Beautiful lashes and great magnetic eyeliner. The eyeliner is totally waterproof and lasts all day without problems. Doesn't irritate my sensitive eyes and these lashes are lightweight and totally beautiful. I have worn them a few different times and they still look beautiful. I am able to clean them gently in makeup remover and then let them dry and I can wear the lashes over and over again.\",\n", + " 'I love using this set when I am wanting to really go all out for my makeup. It makes everything last so much longer and looks so beautiful. It works great with my foundation and all of my makeup. It feels great on the skin and makes my skin so soft and smooth. It also does a great job hydrating my skin and getting it ready for makeup. Everything just works great together and love using it.',\n", + " \"These are very much for the more experienced eyelash wearer as they only have a tiny string to work with and not a strip. So I have to say that if you can't work with just string lashes then do not get these. However, if you don't mind then these are great. They look beautiful and blend in so well that people honestly can't tell they are false lashes.

I honestly love them and they look very natural and beautiful. Would be happy to buy more later on.\",\n", + " \"I'll admit that I do have a nail addiction and I do my nails all of the time. Honestly, it's much cheaper that way. Anyway, normally I don't fool with pushing my cuticles because I'm always loosing the wooden pushers and they always go so dull after using them for a while. Well, now I don't have to keep buying those because this cuticle pusher is awesome and made out of stainless steal. It has a really awesome design, a very nice weight so that it stays in the hand and also can be used to clean out from under the nails too.

I really do love using this though. I always give it a little wipe with an alcohol pad and then do what I need to do. I use the curved ended down to push my cuticles back and then use it face up to clean out from under my nails, because lets face it. It doesn't matter what you do, stuff is still gonna get up in there and you have to clean it out every so often.

Anyway, works great and totally worth the price. Couldn't recommend this enough to everyone.\",\n", + " \"I am totally disappointed with this headband. One it is super cheap and easily bendable which means it will break easily. I have very fine hair so this headband is just horrible with my hair. It sticks up at the top and doesn't hold any hair back because my hair just slides out of it. Now, if someone has very thick hair then this would work perfect for them but for someone like me with very fine hair, this headband just isn't right for me.\",\n", + " \"I have to say that I honestly didn't think this stuff would work or it wouldn't last as long, it would look strange, or that it would make me look plastic like. I didn't know what it would really do but I gave it a chance and tried this stuff. Holy cow does this stuff actually work and it looks awesome and natural. Key word, natural. I used it just like the instructions said and it smoothed out the small lines at the corner of my eyes and under the eyes. It completely reduced the size of my pores on my nose, which are usually very large. I mean, it made my face look great but the real test was how did my make up look over this stuff. Well, it looked wonderful. It made my make up go on smoother than ever before and the real test was the fact it not only lasted all day but even all night until I washed my face. I couldn't believe how well Mistiq actually worked and how great it worked under my make up. This is one product that I completely recommend and suggest it be a staple in every woman's make up bag.\",\n", + " \"I am very pleased with my experience using the Feminine Cleansing Wash. This is very easy to use in the shower as it has a hand pump. The scent is light and pleasant, yet doesn't leave a lingering perfumed odor. I have found that 'regular' soap does me no favors for cleaning my groin area as it's much to harsh for my lady bits. This is a great product to use for those of us that are mindful of our personal hygiene and want to be ready for any situation that comes up between showers. I find this to be a good value for the quality. I certainly will be making this wash a regular order in the future. I hope my experience is helpful as you kindly click the button below.\",\n", + " 'I am happy with my order of the Resin Decorative Accessories Set. This was packaged well and arrived in great condition. What I really like is that this set of tools and inclusions comes in a multi-level box that is transparent. It is easy to see what inclusions are inside, which is very easy to use while working on a project. Pipettes are really great to remove bubbles and also to apply very small amounts of resin into detailed areas. The silicone mat is essential to protect a working surface and the tweezers are very useful to add small items into a poured resin piece. There are also extra 30ml mixing cups, tiny spoons and wooden sticks.

These inclusions are great to use with other materials besides resin like nail art, decoupage glues, acrylic paint and polymer clay. This makes the set versatile for working with different mediums and for different projects. There are full round hole-less beads and also half beads. I really like the tiny seashells, my set also includes a tiny starfish. I am putting these into a resin painting with some sand I saved from a recent beach vacation. The only thing included with this set that is not useful to me are the finger cots, as I prefer to wear gloves when working with resin. The only negative aspect is very small, but some glitter was loose. I did not find this to be bothersome, but did want to mention that. There is a lot of supplies in this kit and I consider it to be a really great value for all that is included. I hope that my experience is helpful as you kindly click the button below.',\n", + " \"I am very happy with my order of the Gershion Pastel Gel Nail Polish Set. These are great to use as it's a nice and even texture. The colors are great for me to use under different stamps, stencils and with stencils for nail art. They also look great as plain colors under a glossy or matte topcoat. I find that it dries easily under my 36 watt lamp. I find this set to be a good value. I hope you find my experience helpful as you kindly click the button below.\",\n", + " \"I have been very happy with my order of the USB Nail File Machine. It works well and is easy to use with the USB cord. I often use this with a battery pack. The accessories have served well and after several months of use are still in good shape. It does great for my nails, but I also use this on my feet. It makes my self-mani and pedis quick and easy. The handle is easy to grip. Speed is quick, but not so much that it's difficult to control. I find that this is a good nail drill for personal use, but I wouldn't recommend it for multiple users as it does start to get warm in my hand when I am finishing on myself. I find it's a very fair value. I hope my experience is helpful and you kindly will click the button below.\",\n", + " 'There are pros and cons to the Tirtyl Hand Soap Sheet Variety Pack. I found it difficult to get a decent lather from the sheets, even when using 2 or 3 at a time. This makes them less than ideal for bathing. However, I did get them to do a great job for cleaning just my hands. I would suggest them for cleaning hands while on the go. The scent is very light when added to water. A tin is included, which is a bit more durable than the paper envelopes. The tin slides open, matchbox style. I would recommend using the tin as it will withstand being transported in a pocket, purse or bag better than the paper envelopes. If you anticipate being exposed to rain, I would suggest to place the tin and/or envelopes into a plastic bag. Using water and friction is superior to using hand sanitizer, and with the soap sheets you will be able to maintain much cleaner hands while out and about.

If you are looking for a portable soap for bathing, I would still suggest to use bar soap wrapped in wax paper inside a plastic bag. If you are in situations where you need to wash hands without soap provided, these are ideal for that need. I would recommend the soap sheets as they are easy to transport and cost effective for hand washing. I hope you find my experience helpful and kindly will click the button below.',\n", + " 'I have a lot of mixed feelings about the Cuckoo Upgraded Eyelash Lift Kit. Primarily, the perm solution is really, really harsh. I cannot recommend the kit if this is the primary component of the kit you want. I would suggest looking elsewhere. On the other hand, the amount of glue rings, wands and microbrushes prove to be very useful to me. If you are after the accessories, then this is a fair value. I have no strong opinion about the pads or scrapers. Overall, this is not a product I would recommend, but if you are after the accessories in the kit, then I would say this is a decent kit to have those on hand. Thanks for reading, if my experience is helpful to you, please click the button below.',\n", + " \"I'm happy with the Fog-free Dental Mirror and 4 Pieces of Stainless Steel Dental Pick. It's packaged securely and all the pieces were in excellent condition upon arrival. I visit my dentist often, but I sometimes need a little help to find rogue bits of debris in some of my teeth. The dental mirror is incredibly handy for that use. I also find the dental picks are better for me as hobby tools. I've never felt the need to scrap my own teeth to risk damage to surrounding tissues. They do a good job in tiny crevices and have a textured handle which is easy to hold. I find this set to be a good value and the versatile use is a great bonus for me.\",\n", + " \"The anmas rucci Acrylic Nail Art Tools Kit gives you a little bit of everything for making your nails, or even crafting creations several different options for creative expression. My favorite part of the set is the half-pearls and pixie beads, but all of the pieces are really pretty. The tape works well with my own adhesive I already had on hand. This is a really fun set and I'd recommend them to anyone that likes to get creative with their nail art!\",\n", + " \"The Butterfly Nail Art Decals Water Transfer Stickers bundle is a great deal. You get 22 full sheets of stickers. Each sheet has over 50 stickers as far as I've counted them. They are either multi-colored and halographic or metallic outlined patterns. Every sheet is a little different, so there are no repeats. They apply easily, but I highly recommend doing a base coat first and a coat on top as well. There are also 2 generously filled jars of holographic butterflies that measure 4mm by 4mm at the widest points. This is a really pretty collection of butterflies and I couldn't recommend them more for both the value and variety!\",\n", + " 'Love this scent ... soft and long lasting when used with the lotion and perfume!!!!!',\n", + " 'Great product, Great hair remover, I loved it! It was so convenient to use. The only issue Iโ€™ve seen is the stickiness doesnโ€™t go away easily it can only be gone by using the cleaning pads.',\n", + " 'Bought this eyebrow trimmer during the pandemic time when all parlours closed. I Couldnโ€™t believe how easy it is to use it and It is completely painless and trims hair with precision',\n", + " 'Good',\n", + " 'This wig is very nice. It fit on okay. The quality seemed fine. It was a good deal. It looked somewhat realisticโ€ฆ obviously not like one of the $500 ones, but it is fine. It was comfortable to wear. It was easy to put on. It was cute. It was fun to wear for everyday use or for a costume. I would recommend it.',\n", + " 'This is a very cute set. It comes with a lot. There were many different colors. The girls really enjoyed it a lot. Everything seemed to be good quality. The packaging looked nice. They love Disney princess, which are very popular. The quality was fine with everything. I would recommend this.',\n", + " 'I love butterflies. This was great for my nails. They were so sparkly. They looked so nice. They were a little tricky to put on, but with practice you will get better. They really were unique. The quality was good. You can give yourself a professional manicure at home for a fraction of the cost. I would recommend them.',\n", + " \"These are great for parties. It has a lot of colors. It is very nice to give a cute look. They went on well. It wasn't too difficult to apply. They looked good. The kids really enjoyed them. They would be good for a party or Halloween. They were lots of fun. I would recommend them.\",\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.
They also helped keep her hair out of her face.',\n", + " 'This came with a lot. It is good to use the different brushes/combs for different times.

They did a good job with my hair. It worked as it was supposed to. It seemed like it was good quality. My hair came out looking nice after I used it. It also seemed durable. It was easy to hold and handle. I was pleased and would recommend it.',\n", + " 'These were so sparkly. I really loved these!!!!

These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.
They also helped keep her hair out of her face.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.
They also helped keep her hair out of her face.',\n", + " 'This mascara was very nice.

I was happy with the makeup. It did a good job of flattering me. It highlighted the good features.

It went on well. It felt fine on. I didnโ€™t have any reactions or problems or anything.

It stayed on fairly well. It didnโ€™t feel too heavy or anything. I was pleased with it.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.
They also helped keep her hair out of her face.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. They also helped keep her hair out of her face. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.',\n", + " 'These nail files are very good. They were sturdy. They did a good job filing my nails. It is nice that you get so many of them. The colors are nice. It is a good value since it comes with so many. It lasts a really long time. I would recommend it.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. They also helped keep her hair out of her face. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.',\n", + " 'This was a very pretty hair comb. The rhinestones looked very nice. It really sparkled. It would be good for a wedding or for another event. It was nicely packaged. It fit in well in my hair. It stayed okay. I like the vintage look. I think it really added to it. You can also wear it for other events than a wedding. It really can compliment the outfit. I thought it seemed durable. I thought the price was fair. I would recommend it.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. They also helped keep her hair out of her face. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.',\n", + " 'These looked very pretty in my daughterโ€™s hair. They really stood out. They looked just like the picture. They went in and out easily. They stayed in fairly well. They were very pretty. She liked them a lot. They really made her look nice. They would also look nice for pictures. They also helped keep her hair out of her face. The quality was pretty decent. It is nice that it is a set and you get a bunch. I liked the variety. I was happy and would recommend it.',\n", + " 'This did a good job with my hair. It worked as it was supposed to. It seemed like it was good quality. My hair came out looking nice after I used it. It also seemed durable. It was easy to hold and handle. I was pleased and would recommend it.',\n", + " \"I had a Norelco years ago, then I went through three Brauns (the micro-foil ones that a straight instead of having three circular blades like this one). All my razors were expensive, they were all the best in the bunch. This is the best by far.

This razor shaves close, I have never felt my skin so smooth except when I used to use a blade. It conforms to your skin, even my neck comes out smooth (about 4 minutes to completely shave smooth, or I'll usually shave for less than a minute and get a shave that lasts until I get home from work). It has a timer that not only tells you exactly how many minutes of battery are left, but it also tells you how many minutes you shaved for (which comes in handy more than I thought it would). The best feature is that you can pop the top up and rinse it in water! My brauns cleaned with refil cartridges that were hard to find and expensive and a hassel; whereas my old Norelco cleaned with a brush and never got really clean. This one cleans easily and quickly, and even beeps to tell you when to clean it! Also, this razor doesn't give me razor burn like my Brauns did!!

If you are a first time shaver, or an expierenced shaver looking for a better shave from an electric razor, this is the one for you! I will never buy any other brand of razor again and I'll probably have this one for years to come...\",\n", + " 'I use these to get myself extra clean after using the restroom. They work wonderfully, stay moist, and are decently priced.',\n", + " 'I got this for my daughter and she decided to give a letter to selected friends. Unfortunately, we will need a few sets to be able to cover all of her good friends.

I think this was a great idea. Friends can attend at school events with the same hair pins to show their friendship or team unity.

Good gift idea!',\n", + " \"This Acetone Free Nail Polish remover is great! It works as well as acetone to remove nail polish and doesn't give off a headache-inducing smell when doing it. In fact, there is a slight perfume smell to it.

The only thing to note is that it leaves the hands oily after use, but that's not a big problem at all.

Highly recommended because it is much less harsh than the traditional method and even more recommended for anyone who gets a headache from the fumes.\",\n", + " \"I got this for my son who is obsessed with my little pony.

The tail is basically a hair clip with synthetic hair glued to it.

The wig tends to shed a bit but that's normal for synthetic hair.

The wig had inner straps to tighten it to different head sizes.

Overall a decent little set for play time.\",\n", + " \"[[VIDEOID:bb5d02bd6cdc2aacb49b1a0f62af91fb]] My husband is a professional tattoo artist and he is always looking for the newest and best equipment.

Tattoo machines are an important part of the tattoo process so having a machine that preforms well is a must have.

The description says this machine is a 3.5 stroke but after using this my husband would have to say he believes it to be a 2.8 stroke in his professional opinion.

When doing the tattoo he had to make several passes to get the line bold enough in the skin versus his other machines. He said this would be fine for doing black and grey tattoos but it is not a good machine to pack color.

The machine is bulky and fits in the hand nice. There is no added weight and it doesn't feel uncomfortable in the hand.

This is a rotary machine so traditional clip cords are not compatible with this.

Overall this is a decent machine. Perfect for an apprentice.

I was selected to review this item at a discount. My reviews are based on quality and performance and are never manipulated or altered in any way.\",\n", + " \"Acne has been an issue for me since puberty. I am always searching for the newest and the best cleansers and treatments.

I really love organic cleansers because they are very gentle on the face and don't load my pores down with nasty chemicals.

This is a charcoal based wash and we all know charcoal is a purifier. This cleanser does not foam, however, you can feel it cleaning. It has a pleasant scent and is amazing at removing makeup. I have found a little bit will do it, you don't have to use a lot of cleanser to clean your face.

I haven't seen any miracle results but I will tell you it does clean well.

Overall a decent cleanser. Price wise a little steep but with Organics you're always going to pay more.

I was selected to review this item at a discount. My reviews are based on personal use, quality and performance and are never manipulated or altered in any way.\",\n", + " \"This had me at Rose Quartz! I'm a rock collector and I am all about beauty so this definitely peaked my interest!

I've been using this for about a week and honestly I haven't seen an improvement in my complexion or anything fancy but this is awesome to use before applying makeup. It seems to grab the makeup and hold it on longer. Weird I know it isn't the intended use but it works! I also use it after I've done my make up to set it. If you compare ingredients to most setting spray that is all natural they are almost identical.

The smell is light and flowery. Definitely has a scent of Rose with a bit of a witch hazel after scent.

The spray itself is medium mist and covers the entire face with one burst. It's very light and absorbs quickly.

This is a nice hydrating mist that has a multitude of uses and I would definitely recommend it.

I was selected to review this item at a discount. My reviews are based on personal use, quality and performance and are never manipulated or altered in any way.\",\n", + " '[[VIDEOID:de92ae908edbae946014f9c8bd24b4e8]] My skin care and health is number one on my priorities. I am always on the lookout for the best products.

This brush is definitely a must have. It has several attachments that keep your skin in is best shape.

I tan in the summer mostly sunless but I also get a natural base tan. Before and after exfoliation is key to keeping a natural looking tan. In the video I am in a bathing suit (wanted to make that clear) and I am preparing to exfoliate before I go to the beach. With this brush you have a body brush, a facial brush, a pumice stone and a facial sponge.

The body brush is great for legs and arms and even backs. The facial brush is Ye best way to deep clean all the makeup residue and grime from your face. The pumice stone is perfect for elbows, knees, ankles and fee. Lastly the sponge is an added bonus for serums and creams.

My only complaint is the need for so many batteries. Other than that definitely a great brush set to have!

I was selected to review this item at a discount. My reviews are based on personal use, quality and performance and are never manipulated or altered in any way.',\n", + " \"[[VIDEOID:f7eef1e0d6ac999bf9c0518a71064d21]] This has two of my favorite things, blackberries and organic ingredients!

I'm going to review each product in the set:

Bubble bath: very thin like water. Produced little to no bubbles and what it did produce dissipated quickly. It does smell amazing.
3/5
Sugar scrub: Very moisturizing. Not to oily and not to dry. It has the right amount of oils. It left my skin silky smooth but my bathtub slippery.
4/5
Bath pillow: Very comfortable, had a bit of a strange smell at first I wiped it down with a cleansing wipe. The suction cups do come out but they are easy to reinsert.
4/5
Soap: Medium lathering it does clean well with no yucky residue.
4/5

In all this is a decent set. I would like to see the bubble bath revamped. Then I could justify the price. As is I would not pay asking price as I could buy a better quality set for the same price.

I was offered a discount to review this item. I paid 10$ out of pocket for this item. My reviews are based on quality and preformance and are never manipulated in any way.\",\n", + " \"I'm a bit of a hair product snob. Years of coloring has damaged my hair badly so I am very picky what I use on it.

Not only is this shampoo organic and not loaded with sulfates and parabens but it has an amazing smell. Almost like a sweet cedar.

The shampoo has a medium lather. I used 10 pumps as I have think and mid length hair. I also left the shampoo in my hair for about 2 minutes.

After washing my hair was not greasy or heavy from residue. There was definitely a shine but no oily feel.

I have oily roots and this shampoo cleaned my hair with easy while leaving it evenly moisturizer.

Overall I am very pleased and I definitely will be purchasing again.

I was selected to review this item for free. My review and assessment is my own after personal use and has not been influenced or compensated.\",\n", + " 'Love this product',\n", + " 'While notes of sea spray and water blossom do evoke the beach, the odd inclusion of \"driftwood\" notes give it a scent that reminds me camp fires. I don\\'t consider this a feminine scent but it would make a nice men\\'s cologne.
Maybe they were going for a unisex scent but for women the addition of notes like orange blossom or coconut might have made it more feminine.

Disappointed.',\n", + " 'These do not connect strongly enough for either the thick or fine hairs. I am nothing but frustrated when I use it.',\n", + " \"First off there is more than enough in this bag for a couple or three soaks. I got a lovely large chunk of rose quartz in my bag and it went for a soak in the tub with me. After a long day of farming duties this stuff really eased my aches. It is nice to have something that works that is already mixed up and I don't have to concoct it myself from all the various elements. Good lavender oil is expensive so this is well worth it.\",\n", + " 'The quality on the sewing at the zipper of these is why I deducted a star. The stitches are big and kind of loose. Repeated use may pull the zipper out. Otherwise the canvas is nice and I think I will do some fabric painting on these.',\n", + " 'These bands are great! I can never buy anything like this so I decided to check Amazon. Great colors, good fit, not too tight, not too lose. Nice wide band and a good look. Great value!',\n", + " 'My family loves this shampoo! I love the fact it has no sulfates! A lot of chemicals are absorbed through your skin so I feel good using this on my family! I have extremely fine,thin,and long hair and by the end of the day my hair is a mess! This shampoo has helped my hair to become flat! I am so glad I got to review this product for free or a discount,because I would have never found such an amazing shampoo! My daughter absolutely loves it!',\n", + " 'The key to having a tattoo that both lasts and looks great for the long term is how itโ€™s cared for during the initial healing process - and this product is perfect to aide in the healing and aftercare.

This moisturizing tattoo lotion is the perfect product to use after cleaning your tattoo. This lotion is excellent at hydrating the skin and holding the moisture without being overly greasy as many of other products tend to be.

This lotion is far cheaper than many other similar products but I found the quality superb. This lotion is much cheaper than what youโ€™ll find at many tattoo studios but every bit as good.

Having a vibrant, great looking tattoo requires properly caring for it through the healing process and after. This lotion is all you need to help your piece of art look great for a lifetime.

Youโ€™ll never regret this purchase.',\n", + " 'The science behind facial skincare has made many discoveries over the last decade and in turn the best skincare products have evolved to take advantage of those findings.

This Sunrise Serum by Merlot is a perfect example of one of these products. Collagen is key to healthy, youthful looking skin - certain ingredients have been found to promote collagen production. This product incorporates the best ingredients known to increase collagen in facial tissue.

In addition this Sunrise Serum has lightening agents that work together to smooth and even skin tone. I was especially interested in this aspect as I have a few sunspots that I want to lighten. Over the several weeks of using this twice a day I can see that it is gradually lightening them. Obviously, I understand any treatment such as this, requires extended daily use to achieve the results Iโ€™m seeking, but based on my initial findings Iโ€™m confident it will work.

This is an excellent product that I absolutely recommend. I look forward to using more Merlot products in the future as I found this serum superb.',\n", + " \"This product makes brushing my Goldendoodle so much easier.

It arrived very quickly and is exactly as described.

It is made to fit on the right hand and has a Velcro type wrist cuff that can be tightened so it doesn't slip around. The plastic tipped bristles cover the entire palm and thumb area making it so you brush large areas with every stroke.

It is made from a breathable fabric which makes it comfortable and cool to wear.

Hair pulls out of the bristles easily when finished brushing so it can be left clean for the next grooming.

It is well made and should last a long time.

I'm very pleased with this purchase.\",\n", + " 'Itโ€™s held together poorly, will not last long. So flimsy! Not worth the high price. This is a dollar store item at best.
Looks lovely though.',\n", + " 'Does not work. Comes right off finger',\n", + " 'These are simple and quick to use and make your feet look and feel good',\n", + " \"Put the Plum color on over hair previously colored Aquamarine and purple and I love the color. I literally only let this dye sit for five minutes and it came out so bright and even. Absolutely gorgeous color!

Be warned it did slightly stain my sink and bathtub, but a good foaming bathroom cleaner, some elbow grease, and a bit of time made quick work of getting rid of it.

The scent is very pleasant, and I also really enjoyed the ease of use and coverage of the dye.

I highly recommend doing a small patch test to make sure it's a color that will look good on you.

The dye came out exactly like the label on the package, absolutely beautiful.\",\n", + " \"This did nothing to remove my color, but it left my hair feeling silky so it's worth 3 stars for that.\",\n", + " 'I followed the instructions carefully and did not get any magnetic effect. It is kind of pretty and the color does shift somewhat. Amazon refunded my purchase so I am still happy.',\n", + " 'These tools are very useful for the ease of cleaning and sturdiness. Not a bad deal.',\n", + " 'I love these hair ties for my breakage prone hair. They are stretchy, soft, have no tight elastic in the middle of them, and the colors are super cute. They feel very well made. Love!',\n", + " 'I travel with these and they are pretty good. Not the ultimate in softness but they definitely donโ€™t suck. They come in a thick travel bag thatโ€™s plastic and pretty fake feeling. Non on the bristles have fallen off and there is a good amount of brush sizes and shapes to choose from. *there is no spoolie with this set. โ˜น๏ธ',\n", + " 'This is the lightest face roller Iโ€™ve used and held. It feels flimsy and like the metal holder will bend/pop out if you push the roller too hard on your face. The smaller roller is really nice to roll over eyes. Feels great! I wish everything felt weighted though. I think there are much better options out there.',\n", + " 'Small travel size of so-so conditioner. Smells great and feels like it rinses out completely but as for conditioning? It just sort of works. So, nothing too special but it doesnโ€™t suck.',\n", + " 'Great product. Made in USA and right upon opening, smells fresh and clean. Like lemons and sunshine. The ziplock bag seals so you can store upright maintain freshness.',\n", + " \"I don't know if this is helping my hair regrowth but, I feel like it's helping my spider veins. It's easy to hold even for extended periods of time. It's not a rechargeable product. It must be plugged in while using. It is painless. I don't wear the super dark glasses. I just close my eyes. I use on underarm too. I will keep it up, I'm just sorta lazy.\",\n", + " 'Wonderful lip balm. Creamy, not waxy and stayed put. Smells luscious and sweet. I feel like this hydrates for at least an hour too. No stinging upon application. The lids audibly \"clicks\" when closed so you know it shut. 45 spf too.',\n", + " \"This serum is so very very good! Smells warm and woodsy in a way, not floral or soapy. Very viscous, medium-heavy. The dropper only dispenses about 4 drops, which is enough for face and neck. I use a roller after applying too, which I highly recommend. I'm happy with the glow and hydration my skin has. The longer I use it, the better my skin looks.\",\n", + " \"My 14 yo is using this set and she loves it. The mascara is a deep black and it doesn't flake off. She also has had no problems removing this product with just a wet makeup wipe. The curler has rubber grips at the end so it is easy for her to hold and use. Very happy with this.\",\n", + " 'This masks works great! My hair is blonde and fine and tends to go brassy if not processed correctly. Using this mask is an easy way to freshen and brighten. Not too thick, almost whipped in texture. Totally moisturizes and rinses out without heavy residue.',\n", + " 'Very decent bamboo toothbrush. Generally the bristles are too soft for me. This one is medium-soft. So at least it feels like my mouth is clean after brushing. Lightweight, no guilt. Even the packaging is made from recycled material. Great to have multi pack!',\n", + " \"This is such a high end product. The weighted compact feels sleek and heavy in your hand. The slide/pivot opening is clever and works smooth. The color saturation is rich and deep and looks flawless on many skin tones. Not too much shimmer, so it actually looks like you've been sun kissed after application. Buildable color if you want a more intense look. You can use both colors together, which is what I do. I am medium complexion, blonde, 48 years old. This product doesn't increase pores size, nor does it settle into any wrinkles. In my opinion, deserving of more than 5 stars.\",\n", + " \"I love oil based cleansers and don't use anything else. But they are not for everyone. My 20 year old daughter doesn't like this product, while I think it's one of the best I've used. The smell is subtle and I love the suppleness of my skin after cleaning!\",\n", + " \"Of all the extensions I've ordered, this is my least favorite. The blonde has so much brass in it! It's almost red in color. (I put a few pictures with my review. The lighter blonde is the color that I expect when I order blonde.) There are also more dark black strands coursing thru these pieces than any other brand I've used. Maybe it's just this particular color? Comes with clips, which is nice. And hair is soft.\",\n", + " 'I only received 1 tube of eyelash serum. I apply it right at my lash line, as directed, on a clean face. Have not seen any notable difference. Does not sting or irritate my eyes.',\n", + " \"This stuff is wonderful. It's been a game changer for my hands this winter. There is very little scent. Which suprised me because it's filled with so many natural extracts like apple, lemon, carrot, aloe, grapefruit. The directions suggest to put on before bed and slip cotton gloves on. I'm not planning on doing that because I'm not 80, but am still very impressed at how long my hands feel protected and moisturized.\",\n", + " \"There's not a lot of salt in here to make it exfoliate very well. That said, it moisturizes and hydrates beautifully. Everything dissolves and washes off completely and it smells so light and fresh!\",\n", + " 'Great for trimming our puppies fur.',\n", + " \"There are no instructions on how to care for the hair extensions nor are there instructions on how to securely put on the halo filament wire (actually a strong, clear plastic line that has 5 adjustable positions AND you get extra wire and snap-in-place comb fasteners).

I had to search YouTube for directions on how to place it securely. I'm still working on getting it the correct size for my head size. I have very thin hair which might be the problem.

There are tons of videos about different hairstyles with halo hair extensions. Plus lots of different updos because YES you can have an updo -- buns, pony tails, braiding etc, -- with these extensions.

Much easier to brush/comb you hair with the halo than with taped extensions. It is NOT itchy like most wigs I've invested in.

I highly recommend this product!\",\n", + " 'I love this stuff, especially for the price. I was looking for a benetint dupe. This has 3x the color payoff for a fraction of the price. I havenโ€™t noticed much plumping action, but the color is so pretty that it doesnโ€™t matter much to me. It smells great and I think it would look good on most skin types so long as you are comfortable with bright reds. My only complaint is that it doesnโ€™t fade evenly but I mean, what lip product does?',\n", + " 'I learned awhile back that Lemon Balm is excellent for stress, which I have plenty of due to health issues. I make two quarts every night for the next day and it really helps me be calm and not worry. Highly recommend!',\n", + " \"We got the burgundy colored one for my wife to complete a costume we were putting together. It's an excellent color, a deep red but not too red that it screams cheap artificial. No, it won't pass as real hair, at this price point I wasn't expecting it to. But I must admit that I'm impressed at the quality for the price. My wife was able to wear it all day and didn't find it uncomfortable at all, and we both loved how she looks in it. Very pleased!\",\n", + " \"It's nice looking, easy to use but I could still smell garlic and onion a but. It did lessen the smell it seemed.\",\n", + " 'This skin is so perfect. It is so easy to tattoo on.',\n", + " 'Muy lindas pero un poco pequeรฑas',\n", + " 'Iโ€™ve been using this brand of mascara for several months without a problem. I received this tube and on the 3rd time using it the stopper at the mouth of the tube that scrapes off some of the mascara fell into the tube. You canโ€™t get it out. So now when you take the brush out of the tube thereโ€™s gobs of mascara on the brush. You have to wipe it off of the brush with a tissue or it canโ€™t be applied. Now Iโ€™m wiping it off the brush and throwing it out. What a waste!',\n", + " 'Really cute headbands. Makes hair look really cute on a bad hair day.',\n", + " \"I have naturally curly hair and don't like to straighten my hair very often since it is so time consuming. This brush only takes a few minutes and then my hair is straight. My ten year old daughter with curly hair also used it and she finds it very easy to use. Price was great also. Hair lazy and frugal mom approved.\",\n", + " \"Pretty but doesn't last for more than two days. It starts chipping or peeling off.\",\n", + " 'My daughter always wants to wear perfume, but her skin is so sensitive. When I saw this, I had to get it. It is hypoallergenic, so it even works well with sensitive skin. The smell is sweet lavender, and smells amazing! It is perfect to apply after bath time.',\n", + " 'These big hair claw clips are amazing! My wife has thick hair and other hair clips are just not large or strong enough to hold all of her hair. These however are large enough and strong enough to hold all of her hair back.

You get a nice variety of 12 different colors and they come in a pretty purple box. They work great for clipping back all of the hair, or in small sections as well when straightening.',\n", + " 'This 4 pack of travel lotions by Spanature is super nice, from the presentation of the product, to the performance of the product. They come packaged soooo nicely in 4 little gift boxes, so they are perfect for gift giving. Also, the tubes are the perfect size to fit in your purse- so they are great for on the go or even traveling!

The lotion itself is very moisturizing, and not greasy at all. The green tea scent is not strong at all, which is perfect if you are sensitive to strong scents.',\n", + " 'This mannequin head is great for the price. It includes the clamp, and the hair is very thick. The hair is not real human hair, itโ€™s synthetic... so it doesnโ€™t curl very good like real human hair.

It is great for trying out new hair styles though, even for practicing hair cutting. It comes with 2 clips and rubber bands as well.',\n", + " 'My wife has always wanted to try magnetic eyelashes, so she decided to give these a shot. They really do work! But, with these practice makes perfect.

They come with 2 tubes of magnetic eyeliner (black), and 10 sets of eyelashes along with the application tool. When you apply the magnetic eyeliner, you have to be precise. The eyeliner is black, and will look very dark if you do too thick of a line. I would do thinner lines if possible, with about 2 layers so that the eyeliner is not overwhelming. Once the eyeliner dries, use the application tool to put the lashes on.

It does feel a bit strange at first (if false lashes are new to you), and it may tickle around your eyes when you blink. But yes, these really work! With more practice my wife will get better at this.

The only thing is that the magnetic eyeliner does not come off easily. You will need a good eye makeup remover to get this off as itโ€™s waterproof!',\n", + " 'These bath bombs are great, especially for the price. You get 18 bath bombs in the box. The box looks like a gift box, so these would make a great gift for someone special! โค๏ธ

The bath bombs are scented with essential oils and are very moisturizing. Each bath bomb is wrapped in tissue paper and labeled. The packaging is just amazing!

The scents are strong, so these may not work for you if you are sensitive to strong scents. I personally think they smell wonderful!',\n", + " 'My wife really likes this perfume by Shakira! It has a nice sweet scent, with a hint of spice. Itโ€™s an incredibly sexy scent that I love too! โค๏ธ It doesnโ€™t last the whole day, however if you reapply in the afternoon, it does. The bottle is beautiful too! Just looks weird with my wife grabbing Shakiraโ€™s bod and spraying. ๐Ÿ˜‚ We got a good laugh out of it!',\n", + " 'This 4 piece hair set is great! My wife has wavy hair, as well as my daughter, and myself. My son has long, curly, coarse hair. This set works on all of our hair types! The largest hollowed our brush is great for blow drying. The smaller comb/brush is designed to remove tangles from curly hair, and it works well when using with detangling spray. There is a small attachment included, which hooks onto the back of the brush to keep the bristles together. You also get a wide tooth comb and a parting comb. Everything included in the set is lightweight and easy to hold. Itโ€™s a great set at an amazing price!',\n", + " 'This hand sanitizer by Puretize is great. During the time of the pandemic, this is a must! It contains 70% alcohol, which is great to kill those nasty germs ๐Ÿฆ ! It smells similar to rubbing alcohol, however itโ€™s not too strong. I love this hand sanitizer as it doesnโ€™t dry out my hands like others. Every family needs a bottle of this in their home!',\n", + " 'My wife has been using this product for about a week and likes it. Itโ€™s very easy to apply, just like clear liquid eyeliner. Itโ€™s good that it does not irritate my wifeโ€™s sensitive skin at all. She has tried on her lashes and has noticed a slight difference in the thickness of them. I am sure that time will bring more dramatic results. The product is a bit pricey for the amount you get though.',\n", + " 'My wife is very happy with this facial cleanser. Itโ€™s very moisturizing and makes her skin feel baby soft after using. It barely has a scent to it and it works great on her sensitive skin.',\n", + " 'My wife loves this stuff! She has been using for a few days and loves the scent! Smells a mix of rose and orange.. beautiful and very uplifting. It makes her skin feel hydrated and more firm. Very nice product!',\n", + " 'These are so nice and easy to apply. You instantly feel the moisture in your skin from the moment you put them on. After taking them off you notice that it really helps with the bags! My wife has used a few times and has already noticed a difference! They are even more refreshing when cold! Just keep them in your fridge!',\n", + " \"Having used this for 2 months now I really am seeing a difference. My skin has always been good, and I have taken care of it for most of my life, so I had a good place to start from, but I am beginning to see the crowsfoot lines fading, the dark shadows fading, and the general quality of skin even nicer.
FYI I am very fair skinned (red hair, white skin, green eyes type of Irish) so not sure how it would work on dark skin, especially African, but it doesn't feel like it's corrosive so might be OK.
You really only need a fingerprint's worth for each eye area, so it is going to last a long time. In 2 months I am less than half way through the jar.\",\n", + " 'WOW a comb that is truly smooth and seam-free, does not snag my long wavy hair, and smells nice. Seems to work well on wet and dry hair. It seems very sturdily made, but I am going to buy another just in case. I just wish they made one with longer tins, as the heavy duty plastic one I had been using before had longer tines and it felt good going through my hair especially when wet. But this is still a very nice product.',\n", + " \"5" is way too long for my waist-length thick hair. The spikes stick out the far side of whatever updo I have going, and make the whole thing look amateurish and unfinished. If these came in 2.5 or 3" they'd be great but they are simply too long.\",\n", + " \"I thought with my short hair this would look bad, but, it's actually quite bohemian sheek!
Love it! It may not be for everyone, but it's for me!\"],\n", + " 'images': [[],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e9Noi7dJL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e9Noi7dJL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e9Noi7dJL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81FN4c0VHzL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81FN4c0VHzL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81FN4c0VHzL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81H68QJM7uL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81H68QJM7uL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81H68QJM7uL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/A1u4jV10XQL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/A1u4jV10XQL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/A1u4jV10XQL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41FMcmkZDLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41FMcmkZDLL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41FMcmkZDLL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41pcNrIv9YL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41pcNrIv9YL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41pcNrIv9YL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51RSDWWsvhL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51RSDWWsvhL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51RSDWWsvhL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61iRbN5WuyL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61iRbN5WuyL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61iRbN5WuyL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51FFKVqctXL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51FFKVqctXL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51FFKVqctXL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51U-Jj8nvvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51U-Jj8nvvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51U-Jj8nvvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51WbXeRwNwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51WbXeRwNwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51WbXeRwNwL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/513UrgWCy4L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/513UrgWCy4L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/513UrgWCy4L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/518Tm388+ML._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/518Tm388+ML._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/518Tm388+ML._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51qo+gHnEwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51qo+gHnEwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51qo+gHnEwL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x9TGPNYpL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x9TGPNYpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x9TGPNYpL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71jSGj3C7+L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71jSGj3C7+L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71jSGj3C7+L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71zc3jpwKZL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71zc3jpwKZL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71zc3jpwKZL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JRU4QveQL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JRU4QveQL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JRU4QveQL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7109uXrMRIL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7109uXrMRIL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7109uXrMRIL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PrdyrY2ZL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PrdyrY2ZL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PrdyrY2ZL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OmgsRmxCL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OmgsRmxCL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OmgsRmxCL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61ZRsMPnINL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61ZRsMPnINL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61ZRsMPnINL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61LtQ1Bn72L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61LtQ1Bn72L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61LtQ1Bn72L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71PPSBL8dLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71PPSBL8dLL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71PPSBL8dLL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61hR2aQ5CFL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61hR2aQ5CFL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61hR2aQ5CFL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/7195jLRRHHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/7195jLRRHHL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/7195jLRRHHL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71om4o9espL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71om4o9espL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71om4o9espL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/51aozdJE2FL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/51aozdJE2FL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/51aozdJE2FL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61j7iT+I5zL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61j7iT+I5zL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61j7iT+I5zL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/51Pf5unNkHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/51Pf5unNkHL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/51Pf5unNkHL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/617WaPj2j8L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/617WaPj2j8L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/617WaPj2j8L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61QfPjskFxL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61QfPjskFxL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61QfPjskFxL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61tAiLsbM5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61tAiLsbM5L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61tAiLsbM5L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71iimioKipL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71iimioKipL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71iimioKipL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71mQIFFUBNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71mQIFFUBNL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71mQIFFUBNL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61AsAyIRdlL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61AsAyIRdlL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61AsAyIRdlL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/711HOIIHXGL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/711HOIIHXGL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/711HOIIHXGL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/810MSsnGxML._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/810MSsnGxML._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/810MSsnGxML._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81nt6AQOJML._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81nt6AQOJML._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81nt6AQOJML._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81477RkXThL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81477RkXThL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81477RkXThL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81LQLQ8lcsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81LQLQ8lcsL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81LQLQ8lcsL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81W-Fm3JRaL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81W-Fm3JRaL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81W-Fm3JRaL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/718JxZzRsNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/718JxZzRsNL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/718JxZzRsNL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81XyalQQ7OL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81XyalQQ7OL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81XyalQQ7OL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81YR-wa-VsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81YR-wa-VsL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81YR-wa-VsL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81bPg319SYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81bPg319SYL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81bPg319SYL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81XXhUch2IL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81XXhUch2IL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81XXhUch2IL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91V7jdv6bnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91V7jdv6bnL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91V7jdv6bnL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/8167aC+7v3L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/8167aC+7v3L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/8167aC+7v3L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81SnZvioJ-L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81SnZvioJ-L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81SnZvioJ-L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91VU45WRgfL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91VU45WRgfL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91VU45WRgfL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81P8ZLSwsiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81P8ZLSwsiL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81P8ZLSwsiL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81TiYaVDE1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81TiYaVDE1L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81TiYaVDE1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81f1JrZA7BL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81f1JrZA7BL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81f1JrZA7BL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813+IAd0YjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813+IAd0YjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813+IAd0YjL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8195-Q43GuL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8195-Q43GuL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8195-Q43GuL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81chu5JJFBL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81chu5JJFBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81chu5JJFBL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91qvXCibQwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91qvXCibQwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91qvXCibQwL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81XaCqJSLrL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81XaCqJSLrL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81XaCqJSLrL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71fN0mmV4uL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71fN0mmV4uL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71fN0mmV4uL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817sRHCKn3L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817sRHCKn3L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817sRHCKn3L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81riP-cfyfL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81riP-cfyfL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81riP-cfyfL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813xcF-eX1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813xcF-eX1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813xcF-eX1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TlNpCIdL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TlNpCIdL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TlNpCIdL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81N+-tbqQLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81N+-tbqQLL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81N+-tbqQLL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lD4ithXrL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lD4ithXrL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lD4ithXrL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91QBVTayYVL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91QBVTayYVL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91QBVTayYVL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71lZIsHJeSL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71lZIsHJeSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71lZIsHJeSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hGrOV6xfL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hGrOV6xfL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hGrOV6xfL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mQo7zt6iL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mQo7zt6iL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mQo7zt6iL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LoSHY4obL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LoSHY4obL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LoSHY4obL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81haJld-nBL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81haJld-nBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81haJld-nBL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81D8nutjN5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81D8nutjN5L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81D8nutjN5L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M3xAgSqYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M3xAgSqYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M3xAgSqYL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g5jsU9AaL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g5jsU9AaL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g5jsU9AaL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Wzk5sbvDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Wzk5sbvDL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Wzk5sbvDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qU252Z1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qU252Z1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qU252Z1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tSTF-y-5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tSTF-y-5L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tSTF-y-5L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91GmvxL2HYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91GmvxL2HYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91GmvxL2HYL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Mmc5QYuwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Mmc5QYuwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Mmc5QYuwL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kbsvOnUBL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kbsvOnUBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kbsvOnUBL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812p1UpCi7L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812p1UpCi7L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812p1UpCi7L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EkzlHnUvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EkzlHnUvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EkzlHnUvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g7xdV34UL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g7xdV34UL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g7xdV34UL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aE5dMh0gL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aE5dMh0gL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aE5dMh0gL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M8hN09rCL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M8hN09rCL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81M8hN09rCL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819uk2Ja3PL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819uk2Ja3PL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819uk2Ja3PL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KEjnb--qL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KEjnb--qL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KEjnb--qL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81p4kpF+DNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81p4kpF+DNL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81p4kpF+DNL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71GBjRzm3pL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71GBjRzm3pL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71GBjRzm3pL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O5olPphvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O5olPphvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O5olPphvL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qAxfA3qCL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qAxfA3qCL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qAxfA3qCL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81sCZG+9VKL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81sCZG+9VKL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81sCZG+9VKL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81c7-mcHeOL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81c7-mcHeOL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81c7-mcHeOL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81cd7Qt3OpL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81cd7Qt3OpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81cd7Qt3OpL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xqDr-24yL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xqDr-24yL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xqDr-24yL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81BfRFfTOYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81BfRFfTOYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81BfRFfTOYL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kR33JLfdL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kR33JLfdL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kR33JLfdL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NLzj9QiWL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NLzj9QiWL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NLzj9QiWL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mUrfB1pqL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mUrfB1pqL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mUrfB1pqL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814BnqrWbjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814BnqrWbjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814BnqrWbjL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91it6i5XYzL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91it6i5XYzL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91it6i5XYzL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AbdE-xqJL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AbdE-xqJL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AbdE-xqJL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xp107fQJL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xp107fQJL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xp107fQJL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ah2FvMACL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ah2FvMACL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ah2FvMACL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Ih4nVvd0L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Ih4nVvd0L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91Ih4nVvd0L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IrnlhfSL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IrnlhfSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IrnlhfSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JbPhFq3pL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JbPhFq3pL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JbPhFq3pL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hPvrTGfFL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hPvrTGfFL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hPvrTGfFL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/910lVuWckpL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/910lVuWckpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/910lVuWckpL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81rMrTImr8L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81rMrTImr8L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81rMrTImr8L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91k6pcZL23L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91k6pcZL23L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91k6pcZL23L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Kmuk16QVL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Kmuk16QVL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Kmuk16QVL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UgKlcUk1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UgKlcUk1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UgKlcUk1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81dqBuCcuNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81dqBuCcuNL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81dqBuCcuNL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zOBtpQ0iL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zOBtpQ0iL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zOBtpQ0iL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+k8kPDptL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+k8kPDptL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+k8kPDptL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813DLxPKu7L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813DLxPKu7L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/813DLxPKu7L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814iznb41gL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814iznb41gL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/814iznb41gL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81IWtVncjnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81IWtVncjnL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81IWtVncjnL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TjVlrlQYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TjVlrlQYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TjVlrlQYL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q7ufZQLpL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q7ufZQLpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q7ufZQLpL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mzoE-G5zL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mzoE-G5zL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mzoE-G5zL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zcuXRVhKL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zcuXRVhKL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zcuXRVhKL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kF6RSW1GL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kF6RSW1GL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kF6RSW1GL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91ur82XpxiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91ur82XpxiL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91ur82XpxiL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OwT6XhF-L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OwT6XhF-L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OwT6XhF-L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ZIJMn7CHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ZIJMn7CHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ZIJMn7CHL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UIisyxLWL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UIisyxLWL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81UIisyxLWL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81uvFhZgavL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81uvFhZgavL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81uvFhZgavL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91AXsTxyOnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91AXsTxyOnL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91AXsTxyOnL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81V1z3PDZxL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81V1z3PDZxL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81V1z3PDZxL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xB3kMSaIL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xB3kMSaIL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xB3kMSaIL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yNTfUme9L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yNTfUme9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yNTfUme9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91G972aNUjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91G972aNUjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91G972aNUjL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817CpxZOK1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817CpxZOK1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/817CpxZOK1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819ycuv-c9L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819ycuv-c9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819ycuv-c9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81B1D0MIwEL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81B1D0MIwEL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81B1D0MIwEL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LjxVB95BL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LjxVB95BL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LjxVB95BL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81QU2N5fZmL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81QU2N5fZmL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81QU2N5fZmL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81WosEgrmAL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81WosEgrmAL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81WosEgrmAL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xIeKrZBRL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xIeKrZBRL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xIeKrZBRL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yeYtqddrL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yeYtqddrL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81yeYtqddrL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91VDL+Din9L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91VDL+Din9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91VDL+Din9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91lqxlrt57L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91lqxlrt57L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91lqxlrt57L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SjTa2JrTL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SjTa2JrTL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SjTa2JrTL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ov190qbbL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ov190qbbL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ov190qbbL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811m4jF6dbL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811m4jF6dbL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811m4jF6dbL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TffM7zSL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TffM7zSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819TffM7zSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81HBhIleRUL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81HBhIleRUL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81HBhIleRUL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KfsY57bsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KfsY57bsL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81KfsY57bsL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tFbwZKIfL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tFbwZKIfL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tFbwZKIfL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ypO9O3LeL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ypO9O3LeL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ypO9O3LeL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812hP2IoMkL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812hP2IoMkL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812hP2IoMkL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zHiXkz4sL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zHiXkz4sL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zHiXkz4sL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ptvt6NwHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ptvt6NwHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Ptvt6NwHL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+5BkUBY+L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+5BkUBY+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+5BkUBY+L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+XRW9U4mL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+XRW9U4mL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81+XRW9U4mL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LkYBGyhKL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LkYBGyhKL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LkYBGyhKL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xbFc2WRaL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xbFc2WRaL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81xbFc2WRaL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91sQF1weqHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91sQF1weqHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91sQF1weqHL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qpdH-t7L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qpdH-t7L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/812qpdH-t7L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bugYnkehL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bugYnkehL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bugYnkehL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71l6nq3kr+L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71l6nq3kr+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71l6nq3kr+L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GiNjEZDxL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GiNjEZDxL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GiNjEZDxL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81-YSqdIx6L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81-YSqdIx6L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81-YSqdIx6L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NKmqHVsiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NKmqHVsiL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NKmqHVsiL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819BYFVaCvL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819BYFVaCvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/819BYFVaCvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fJ+TresHL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fJ+TresHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fJ+TresHL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q1-gBqO6L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q1-gBqO6L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Q1-gBqO6L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PwR8S+ZbL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PwR8S+ZbL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71PwR8S+ZbL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816zl2Um6RL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816zl2Um6RL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816zl2Um6RL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61GGYCwmJVL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61GGYCwmJVL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61GGYCwmJVL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N8T2rvOeL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N8T2rvOeL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N8T2rvOeL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hJlaUqrxL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hJlaUqrxL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hJlaUqrxL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x4eWqEQUL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x4eWqEQUL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71x4eWqEQUL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wYkEnFYuL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wYkEnFYuL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wYkEnFYuL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kcLpmaAbL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kcLpmaAbL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kcLpmaAbL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DJj1cKAwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DJj1cKAwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DJj1cKAwL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71n4hQYnZaL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71n4hQYnZaL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71n4hQYnZaL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71WIsPz52mL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71WIsPz52mL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71WIsPz52mL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71kDczl3TIL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71kDczl3TIL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71kDczl3TIL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/712j0jVb59L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/712j0jVb59L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/712j0jVb59L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71L7L-4ydYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71L7L-4ydYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71L7L-4ydYL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81J4zB0XxsL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81J4zB0XxsL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81J4zB0XxsL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NNUly9mbL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NNUly9mbL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81NNUly9mbL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OxUJA7J+L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OxUJA7J+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81OxUJA7J+L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71bKcXTS4JL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71bKcXTS4JL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71bKcXTS4JL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71gHH7xGv5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71gHH7xGv5L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71gHH7xGv5L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71qFuJzN9qL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71qFuJzN9qL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71qFuJzN9qL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81fNprMsgrL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81fNprMsgrL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81fNprMsgrL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/913uZIcmIzL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/913uZIcmIzL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/913uZIcmIzL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91hZ9d7i87L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91hZ9d7i87L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91hZ9d7i87L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/813pdijmDvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/813pdijmDvL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/813pdijmDvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/815GyUZZVrL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/815GyUZZVrL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/815GyUZZVrL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81DR56GGksL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81DR56GGksL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81DR56GGksL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81Vg1rao1uL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81Vg1rao1uL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81Vg1rao1uL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81qqOFKCuFL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81qqOFKCuFL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81qqOFKCuFL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/810hpN2DDDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/810hpN2DDDL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/810hpN2DDDL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/811oWbOgScL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/811oWbOgScL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/811oWbOgScL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81kTT4uwd3L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81kTT4uwd3L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81kTT4uwd3L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81hkzSwQfIL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81hkzSwQfIL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81hkzSwQfIL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91mqaaFiIIL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91mqaaFiIIL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91mqaaFiIIL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71DXKhoE8XL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71DXKhoE8XL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71DXKhoE8XL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81Ec6TuQIXL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81Ec6TuQIXL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81Ec6TuQIXL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81ZdNahnH-L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81ZdNahnH-L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81ZdNahnH-L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91kio6wqJEL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91kio6wqJEL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91kio6wqJEL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/911jeQTCJiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/911jeQTCJiL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/911jeQTCJiL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91zORzCzfcL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91zORzCzfcL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91zORzCzfcL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/910+61Fb-EL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/910+61Fb-EL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/910+61Fb-EL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91mo+n1WbNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91mo+n1WbNL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91mo+n1WbNL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/917GSwiJ9iL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/917GSwiJ9iL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/917GSwiJ9iL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91oRFYRS4eL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91oRFYRS4eL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91oRFYRS4eL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91qZVfcc8DL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91qZVfcc8DL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91qZVfcc8DL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91ZlQUduQeL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91ZlQUduQeL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91ZlQUduQeL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91+ZpZfZYbL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91+ZpZfZYbL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91+ZpZfZYbL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91GWGQbeHFL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91GWGQbeHFL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91GWGQbeHFL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81M7Bfn8qDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81M7Bfn8qDL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81M7Bfn8qDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81XAR7K4QUL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81XAR7K4QUL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81XAR7K4QUL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91-w7fsyR5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91-w7fsyR5L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91-w7fsyR5L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91o00X0cDdL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91o00X0cDdL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91o00X0cDdL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/813+3sgLApL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/813+3sgLApL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/813+3sgLApL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81P2UjkjkJL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81P2UjkjkJL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81P2UjkjkJL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zTw-3J6wL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zTw-3J6wL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81zTw-3J6wL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tlHZKzZWL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tlHZKzZWL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81tlHZKzZWL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91uZe5QV7AL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91uZe5QV7AL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91uZe5QV7AL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qNeWO+nqL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qNeWO+nqL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81qNeWO+nqL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Fxdpf6v+L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Fxdpf6v+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Fxdpf6v+L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81d9eTLLWSL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81d9eTLLWSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81d9eTLLWSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g8wJkOwQL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g8wJkOwQL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81g8wJkOwQL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61+zioVpeOL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61+zioVpeOL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61+zioVpeOL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71KrAcjziEL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71KrAcjziEL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71KrAcjziEL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61sT1UmjeGL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61sT1UmjeGL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61sT1UmjeGL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611btPJtJAL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611btPJtJAL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611btPJtJAL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61JGa6s6IiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61JGa6s6IiL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61JGa6s6IiL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/717vEMMJyyL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/717vEMMJyyL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/717vEMMJyyL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71LuBAgHFQL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71LuBAgHFQL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71LuBAgHFQL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61MXpwPrT0L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61MXpwPrT0L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61MXpwPrT0L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TAecN4guL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TAecN4guL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TAecN4guL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z+3bM6QFL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z+3bM6QFL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z+3bM6QFL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yXFY5KvtL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yXFY5KvtL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yXFY5KvtL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/31kydAzu1tL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/31kydAzu1tL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/31kydAzu1tL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/41XjKyuSFUL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/41XjKyuSFUL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/41XjKyuSFUL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41kq3NvQnHL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41kq3NvQnHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41kq3NvQnHL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/411eElUONpL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/411eElUONpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/411eElUONpL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/417Zpwn7gwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/417Zpwn7gwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/417Zpwn7gwL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41RrqYnYwuL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41RrqYnYwuL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41RrqYnYwuL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41aiilnncnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41aiilnncnL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41aiilnncnL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41qnTi485gL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41qnTi485gL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41qnTi485gL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41yV8NjAVmL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41yV8NjAVmL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41yV8NjAVmL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61OLAHxNysL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61OLAHxNysL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61OLAHxNysL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41I9K+HFXsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41I9K+HFXsL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41I9K+HFXsL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41eYjxX+WLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41eYjxX+WLL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41eYjxX+WLL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41reyYVxf9L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41reyYVxf9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41reyYVxf9L._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Kl9WYDP1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Kl9WYDP1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Kl9WYDP1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Qxo8cJrkL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Qxo8cJrkL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41Qxo8cJrkL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41e6glYxm1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41e6glYxm1L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41e6glYxm1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41frN6PjJ9L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41frN6PjJ9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41frN6PjJ9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41j146vb99L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41j146vb99L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/41j146vb99L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J2kJV0X8L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J2kJV0X8L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J2kJV0X8L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ncz-feiLL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ncz-feiLL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81ncz-feiLL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91DFNrYy8bL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91DFNrYy8bL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91DFNrYy8bL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/819hUNDnkxL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/819hUNDnkxL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/819hUNDnkxL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81C-xRzHGsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81C-xRzHGsL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81C-xRzHGsL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/615BprZl2NL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/615BprZl2NL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/615BprZl2NL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61OZXayJCzL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61OZXayJCzL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61OZXayJCzL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61teuy2NNKL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61teuy2NNKL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61teuy2NNKL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/51JYp31e62L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/51JYp31e62L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/51JYp31e62L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/51TFWRrfgDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/51TFWRrfgDL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/51TFWRrfgDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71NYJCzhZiL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71NYJCzhZiL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71NYJCzhZiL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61pcIRZ-SlL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61pcIRZ-SlL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61pcIRZ-SlL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81K9p8YI1tL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81K9p8YI1tL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81K9p8YI1tL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81b+xkib7GL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81b+xkib7GL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81b+xkib7GL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51z-A34UATL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51z-A34UATL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51z-A34UATL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61YoSUSUCkL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61YoSUSUCkL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61YoSUSUCkL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71BwBFmed+L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71BwBFmed+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71BwBFmed+L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61r2XpOUzNL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61r2XpOUzNL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61r2XpOUzNL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61+qw48hplL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61+qw48hplL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61+qw48hplL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61J5QpMVCuL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61J5QpMVCuL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61J5QpMVCuL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61k-lsV-n1L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61k-lsV-n1L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61k-lsV-n1L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61qvzo5ErnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61qvzo5ErnL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61qvzo5ErnL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61uwmhWEAjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61uwmhWEAjL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61uwmhWEAjL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IJvTg71L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IJvTg71L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/816IJvTg71L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EYXTwUD4L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EYXTwUD4L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81EYXTwUD4L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81JaLObS98L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aohA4a0DL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aohA4a0DL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aohA4a0DL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/612CfWQ5tAL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/612CfWQ5tAL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/612CfWQ5tAL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71rAen5GjLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71rAen5GjLL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71rAen5GjLL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71Y4NJfz+GL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71Y4NJfz+GL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71Y4NJfz+GL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71eW-CJoEDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71eW-CJoEDL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71eW-CJoEDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71mcD3scyML._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71mcD3scyML._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71mcD3scyML._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91v5dndy+FL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91v5dndy+FL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91v5dndy+FL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1Rfzru-7nL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1Rfzru-7nL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1Rfzru-7nL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1jbyX+UcvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1jbyX+UcvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1jbyX+UcvL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91g8xEGs0IL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91g8xEGs0IL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91g8xEGs0IL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1193dGHbpS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1193dGHbpS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1193dGHbpS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B11Szd7gVIS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B11Szd7gVIS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B11Szd7gVIS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B13Xha09h1S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B13Xha09h1S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B13Xha09h1S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B190gdBFBBS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B190gdBFBBS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B190gdBFBBS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1ABX7B2eAS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1ABX7B2eAS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1ABX7B2eAS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1AyhY782FS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1AyhY782FS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1AyhY782FS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C0jOlMVzS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C0jOlMVzS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C0jOlMVzS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1DozBDOcrS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1DozBDOcrS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1DozBDOcrS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1LOCaRwe4S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1LOCaRwe4S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1LOCaRwe4S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1YF5ibIObS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1YF5ibIObS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1YF5ibIObS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1hpeY1biXS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1hpeY1biXS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1hpeY1biXS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1n-WBTVl1S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1n-WBTVl1S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1n-WBTVl1S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1oVGDE+zTS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1oVGDE+zTS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1oVGDE+zTS._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PmhkvJoiS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PmhkvJoiS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PmhkvJoiS._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/914cEwFmVSL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/914cEwFmVSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/914cEwFmVSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91UgU6gsUdL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91UgU6gsUdL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91UgU6gsUdL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8161tpAFX2L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8161tpAFX2L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8161tpAFX2L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91NaLJXqpTL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91NaLJXqpTL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91NaLJXqpTL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1HXU2-u6GL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1HXU2-u6GL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1HXU2-u6GL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1j2ZSti-5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1j2ZSti-5L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1j2ZSti-5L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1y-sl2PTtL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1y-sl2PTtL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1y-sl2PTtL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1AoVenMIwL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1AoVenMIwL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A1AoVenMIwL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PhwOU4+4S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PhwOU4+4S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1PhwOU4+4S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1dcm+m3uDS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1dcm+m3uDS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1dcm+m3uDS._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lfesHr6HL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lfesHr6HL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81lfesHr6HL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EHw0SOtZS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EHw0SOtZS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EHw0SOtZS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1SbGayY31S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1SbGayY31S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1SbGayY31S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1S3i56adqS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1S3i56adqS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1S3i56adqS._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C-ESQDz6S._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C-ESQDz6S._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1C-ESQDz6S._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EB3iluvAS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EB3iluvAS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1EB3iluvAS._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A10XI7vvB0L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A10XI7vvB0L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/A10XI7vvB0L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1tkEmoILpS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1tkEmoILpS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/B1tkEmoILpS._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qAm6XHKtL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qAm6XHKtL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qAm6XHKtL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81osCoIA91L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81osCoIA91L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81osCoIA91L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FkGwE7+CL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FkGwE7+CL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FkGwE7+CL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z9FFN5gdL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z9FFN5gdL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61z9FFN5gdL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71JOZblqzsL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71JOZblqzsL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71JOZblqzsL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZdEAJWBAL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZdEAJWBAL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZdEAJWBAL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7119-5nTjZL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7119-5nTjZL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7119-5nTjZL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/713gnvD-WvL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/713gnvD-WvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/713gnvD-WvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J3E+L-VSL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J3E+L-VSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71J3E+L-VSL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bo1ppcfML.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bo1ppcfML._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bo1ppcfML._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71j86EZ7-FL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71j86EZ7-FL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71j86EZ7-FL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GouLn8OaL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GouLn8OaL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81GouLn8OaL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81crMXfQFSL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81crMXfQFSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81crMXfQFSL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-kiBJ+cyL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-kiBJ+cyL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-kiBJ+cyL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FxPcV1BxL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FxPcV1BxL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61FxPcV1BxL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71uQh+6sQcL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71uQh+6sQcL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71uQh+6sQcL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kVZ4yBuBL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kVZ4yBuBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81kVZ4yBuBL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71+QviMvxDL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71+QviMvxDL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71+QviMvxDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DrRBbw-aL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DrRBbw-aL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71DrRBbw-aL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71vo8tYChHL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fQRYSn6ML.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fQRYSn6ML._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fQRYSn6ML._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71B2YT4naOL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71B2YT4naOL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71B2YT4naOL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TPwDoCKoL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TPwDoCKoL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TPwDoCKoL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TiGPqVg9L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TiGPqVg9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71TiGPqVg9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71g-iEN9beL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71g-iEN9beL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71g-iEN9beL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71od9LJbhEL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71od9LJbhEL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71od9LJbhEL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qwdOq4WKL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qwdOq4WKL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71qwdOq4WKL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yKPnR68NL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yKPnR68NL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yKPnR68NL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TQIOR8M4L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TQIOR8M4L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81TQIOR8M4L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-kT8fSXDL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-kT8fSXDL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-kT8fSXDL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-lm0H-mBL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-lm0H-mBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-lm0H-mBL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611ohRQ3+TL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611ohRQ3+TL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/611ohRQ3+TL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61I8sEvUZYL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61I8sEvUZYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61I8sEvUZYL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Ke8jAWnvL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Ke8jAWnvL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61Ke8jAWnvL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61R6S3lZ-lL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61R6S3lZ-lL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61R6S3lZ-lL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61gpemg-QhL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61gpemg-QhL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61gpemg-QhL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71cq6qONV4L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71cq6qONV4L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71cq6qONV4L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71jiwd8hT9L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71jiwd8hT9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71jiwd8hT9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71z8O5AHqXL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71z8O5AHqXL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71z8O5AHqXL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61psmjrNtIL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61psmjrNtIL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61psmjrNtIL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hcDFSrPjL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hcDFSrPjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71hcDFSrPjL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Db5NUnS-L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Db5NUnS-L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Db5NUnS-L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aRShc5vNL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aRShc5vNL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81aRShc5vNL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-Hx9N7wyL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-Hx9N7wyL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71-Hx9N7wyL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rE4pvbJVL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rE4pvbJVL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rE4pvbJVL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1Dzjig2JsS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1Dzjig2JsS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1Dzjig2JsS._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1L1Roh6NKS._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1L1Roh6NKS._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/C1L1Roh6NKS._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61uAbo1SaGL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61uAbo1SaGL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61uAbo1SaGL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61vWFuWdt+L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61vWFuWdt+L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61vWFuWdt+L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Hm87IFxBL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Hm87IFxBL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Hm87IFxBL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Y3aKZfyJL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Y3aKZfyJL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Y3aKZfyJL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wv02+DL8L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wv02+DL8L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71wv02+DL8L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61F4IyPuERL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61F4IyPuERL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61F4IyPuERL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61TMuF69ATL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61TMuF69ATL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61TMuF69ATL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61dP2eucvYL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61dP2eucvYL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61dP2eucvYL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/51Fxh7NpBlL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/51Fxh7NpBlL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/51Fxh7NpBlL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81yMD7rLQzL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81yMD7rLQzL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81yMD7rLQzL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/91Q6Npds7rL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/91Q6Npds7rL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/91Q6Npds7rL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81QJpc52x4L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81QJpc52x4L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81QJpc52x4L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/910OeRf82DL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/910OeRf82DL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/910OeRf82DL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/914A+y2KuvL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/914A+y2KuvL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/914A+y2KuvL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81q0SEOk4BL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81q0SEOk4BL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81q0SEOk4BL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81zRRbNGwML._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81zRRbNGwML._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81zRRbNGwML._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/71D-fenQR4L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/71D-fenQR4L._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/71D-fenQR4L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SxT2E2ekL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SxT2E2ekL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81SxT2E2ekL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91-NjIS8wpL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91-NjIS8wpL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91-NjIS8wpL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811zJbLn1BL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811zJbLn1BL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/811zJbLn1BL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fwdCqqX8L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fwdCqqX8L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81fwdCqqX8L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mXbcoUU5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mXbcoUU5L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81mXbcoUU5L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91bvRKVQcnL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91bvRKVQcnL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/91bvRKVQcnL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Brocb4vGL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Brocb4vGL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71Brocb4vGL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71IybCmmhDL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71IybCmmhDL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71IybCmmhDL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZU0ZcU92L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZU0ZcU92L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZU0ZcU92L._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mu6NT6myL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mu6NT6myL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mu6NT6myL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71iQZmuQejL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71iQZmuQejL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71iQZmuQejL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XF3aeiimL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XF3aeiimL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XF3aeiimL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51UHR0wIdLL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51UHR0wIdLL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/51UHR0wIdLL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N7JMzJzAL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N7JMzJzAL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61N7JMzJzAL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8124tg-dLnL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8124tg-dLnL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/8124tg-dLnL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O0b-A1dkL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O0b-A1dkL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81O0b-A1dkL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LT072jVjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LT072jVjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81LT072jVjL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mlmDHfElL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mlmDHfElL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71mlmDHfElL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81PObD5BkhL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81PObD5BkhL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81PObD5BkhL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OsAQYWMZL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OsAQYWMZL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71OsAQYWMZL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61jRcki1fCL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61jRcki1fCL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61jRcki1fCL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71b8wsPAF3L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71b8wsPAF3L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71b8wsPAF3L._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-t9rcYFdL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-t9rcYFdL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61-t9rcYFdL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IlmDLru9L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IlmDLru9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IlmDLru9L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/710ms5A8gOL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/710ms5A8gOL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/710ms5A8gOL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AFry8gt2L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AFry8gt2L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61AFry8gt2L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/711mTw-1U7L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/711mTw-1U7L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/711mTw-1U7L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e8oceQH8L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e8oceQH8L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71e8oceQH8L._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71HvKJlf4gL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71HvKJlf4gL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71HvKJlf4gL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZBnFas87L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZBnFas87L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZBnFas87L._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yjGQgvU6L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yjGQgvU6L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71yjGQgvU6L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61osTk3xvtL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61osTk3xvtL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61osTk3xvtL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61E3smvzJNL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61E3smvzJNL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61E3smvzJNL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61mo-ffshYL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61mo-ffshYL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61mo-ffshYL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/61lA69soGVL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/61lA69soGVL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/61lA69soGVL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/812t+n+b3cL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/812t+n+b3cL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/812t+n+b3cL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://m.media-amazon.com/images/I/81WZvjhXocL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://m.media-amazon.com/images/I/81WZvjhXocL._SL800_.jpg',\n", + " 'small_image_url': 'https://m.media-amazon.com/images/I/81WZvjhXocL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Lw+UemwCL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Lw+UemwCL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Lw+UemwCL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hjkvmZF5L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hjkvmZF5L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81hjkvmZF5L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZDwn203hL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZDwn203hL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ZDwn203hL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bdJ29IWPL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bdJ29IWPL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71bdJ29IWPL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81AB1XED6iL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81AB1XED6iL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81AB1XED6iL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Oc7q2+1EL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Oc7q2+1EL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81Oc7q2+1EL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81h+sCS3tuL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81h+sCS3tuL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/81h+sCS3tuL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61cH6S9vwuL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61cH6S9vwuL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61cH6S9vwuL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rN5unUQ6L._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rN5unUQ6L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71rN5unUQ6L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7182p+rYmZL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7182p+rYmZL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/7182p+rYmZL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71MD1gc2q9L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71MD1gc2q9L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71MD1gc2q9L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61LRfpftojL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61LRfpftojL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61LRfpftojL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TMMeGspaL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TMMeGspaL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61TMMeGspaL._SL256_.jpg'}],\n", + " [],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XlGpLvzxL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XlGpLvzxL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61XlGpLvzxL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61zt0hZovSL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61zt0hZovSL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61zt0hZovSL._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IOjlBk59L.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IOjlBk59L._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61IOjlBk59L._SL256_.jpg'}],\n", + " [{'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61er2Tu1UjL._SL1600_.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61er2Tu1UjL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/61er2Tu1UjL._SL256_.jpg'},\n", + " {'attachment_type': 'IMAGE',\n", + " 'large_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ebnomuLOL.jpg',\n", + " 'medium_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ebnomuLOL._SL800_.jpg',\n", + " 'small_image_url': 'https://images-na.ssl-images-amazon.com/images/I/71ebnomuLOL._SL256_.jpg'}],\n", + " [],\n", + " [],\n", + " [],\n", + " []],\n", + " 'asin': ['B00YQ6X8EO',\n", + " 'B081TJ8YS3',\n", + " 'B07PNNCSP9',\n", + " 'B09JS339BZ',\n", + " 'B08BZ63GMJ',\n", + " 'B00R8DXL44',\n", + " 'B099DRHW5V',\n", + " 'B088SZDGXG',\n", + " 'B08P2DZB4X',\n", + " 'B086QY6T7N',\n", + " 'B08DHTJ25J',\n", + " 'B07RBSLNFR',\n", + " 'B07SLFWZKN',\n", + " 'B08JTNQFZY',\n", + " 'B08GLG6W8T',\n", + " 'B08M3C6LVS',\n", + " 'B07GHPCT6T',\n", + " 'B07KG1TWP5',\n", + " 'B07W397QG4',\n", + " 'B07GDQPG12',\n", + " 'B07J3GH1W1',\n", + " 'B01M7UMAUG',\n", + " 'B00JMDPK8S',\n", + " 'B01ETWL5B2',\n", + " 'B07ZJKVVLW',\n", + " 'B082QX2HP6',\n", + " 'B077SRDVG9',\n", + " 'B01AKTGHFW',\n", + " 'B079SMVSYW',\n", + " 'B07K8VTT6M',\n", + " 'B083BDVS36',\n", + " 'B07H6YGKVJ',\n", + " 'B0BFR5WF1R',\n", + " 'B00946GD7K',\n", + " 'B082FLP15V',\n", + " 'B0020MKBNW',\n", + " 'B00023J4AW',\n", + " 'B005IYYF5E',\n", + " 'B07577WHPQ',\n", + " 'B01M5KNSQN',\n", + " 'B07KDNK11M',\n", + " 'B08DLGCYK8',\n", + " 'B081GCFHPG',\n", + " 'B07H8Z3SMK',\n", + " 'B08C9LZQN4',\n", + " 'B07H281V4V',\n", + " 'B09FF97RHL',\n", + " 'B07Y5QX37B',\n", + " 'B07XYXSYCD',\n", + " 'B07NSR3CKR',\n", + " 'B018T2SNE0',\n", + " 'B018F28B1Y',\n", + " 'B01HO1ZB7Y',\n", + " 'B0040NQBAG',\n", + " 'B00JNI1DZQ',\n", + " 'B07T2L6JQR',\n", + " 'B095SC4J8T',\n", + " 'B087JNH3NC',\n", + " 'B07SQ8193F',\n", + " 'B09CQ4PXLN',\n", + " 'B08DXDLR3P',\n", + " 'B0875V791H',\n", + " 'B07LBK2YQX',\n", + " 'B07FX94GYX',\n", + " 'B08CXFDDV8',\n", + " 'B015RR870U',\n", + " 'B000OQFVLS',\n", + " 'B00C0YZBJE',\n", + " 'B0B8DCC531',\n", + " 'B0B4JP5YD9',\n", + " 'B0B4JPGX8P',\n", + " 'B09KT4RJG6',\n", + " 'B07KQ32Z8C',\n", + " 'B08PQ6YXSH',\n", + " 'B07W6H8CGT',\n", + " 'B08ZSR9HLF',\n", + " 'B08KYLTK5H',\n", + " 'B08KWN77LW',\n", + " 'B08HXQ3T9K',\n", + " 'B08C52KD43',\n", + " 'B08G6FBFSJ',\n", + " 'B08FRQGYDF',\n", + " 'B08BZ1RHPS',\n", + " 'B085NYYLQ8',\n", + " 'B085WTCBLG',\n", + " 'B088FBNQXW',\n", + " 'B087D7MVHB',\n", + " 'B07PRDZ2BH',\n", + " 'B083TLNBJJ',\n", + " 'B082NKQ4ZT',\n", + " 'B084D86YL8',\n", + " 'B07WNBZQGT',\n", + " 'B07SW7D6ZR',\n", + " 'B07JDD2L3M',\n", + " 'B082MTTFZD',\n", + " 'B07NPWK167',\n", + " 'B07J2QZBTP',\n", + " 'B07N45YN6C',\n", + " 'B077YR3333',\n", + " 'B07FZ5HZLM',\n", + " 'B07KV31WDS',\n", + " 'B07GDQPG12',\n", + " 'B071R2QPF3',\n", + " 'B01KJPFO9W',\n", + " 'B01B6V11UY',\n", + " 'B00GUTPV4A',\n", + " 'B01CO73OIQ',\n", + " 'B00KR4AFJU',\n", + " 'B015ZXMSFQ',\n", + " 'B00KXFD75M',\n", + " 'B010B0S67C',\n", + " 'B00MDKICPK',\n", + " 'B00NNKWDI6',\n", + " 'B00N6WHTRG',\n", + " 'B0943GJDP6',\n", + " 'B0008F6QGO',\n", + " 'B08SWV1X6D',\n", + " 'B08JLXLJGS',\n", + " 'B089K4SV23',\n", + " 'B00KNIECVC',\n", + " 'B088838886',\n", + " 'B01FVUMG28',\n", + " 'B0093EQX6Y',\n", + " 'B00JM1BZUW',\n", + " 'B07KDNK11M',\n", + " 'B08K41B227',\n", + " 'B00EIL38WO',\n", + " 'B003USID1C',\n", + " 'B01N070HWY',\n", + " 'B00G7UFXJA',\n", + " 'B0B7RBK4NJ',\n", + " 'B010B5ZE4U',\n", + " 'B09SGXNB25',\n", + " 'B071JNRJX2',\n", + " 'B08XJWLLKQ',\n", + " 'B08PLFZB89',\n", + " 'B08KHRF9NY',\n", + " 'B08N6YHQXT',\n", + " 'B08SQ31H8P',\n", + " 'B08LZLBXYT',\n", + " 'B08NPBQR9L',\n", + " 'B08P8BN9BZ',\n", + " 'B08BLX72TP',\n", + " 'B08LYT4Q2X',\n", + " 'B0841WQNNZ',\n", + " 'B087ZQK2G8',\n", + " 'B087Z9X39L',\n", + " 'B07XQKH3RY',\n", + " 'B084ZHP45Y',\n", + " 'B07LCHCD6Q',\n", + " 'B07H3S8WTV',\n", + " 'B071JMGPTH',\n", + " 'B07F8PCLDV',\n", + " 'B07J3GH1W1',\n", + " 'B07FM69672',\n", + " 'B07DSQ3NWM',\n", + " 'B0792Q3T59',\n", + " 'B01NCWHH2W',\n", + " 'B07NGCSZYY',\n", + " 'B07SSLTKHX',\n", + " 'B07G19ZXWB',\n", + " 'B083SCVG16',\n", + " 'B07V6F1TK2',\n", + " 'B01HTO9T2Y',\n", + " 'B014C578R6',\n", + " 'B01MXLP1T1',\n", + " 'B01G5TZ6BM',\n", + " 'B0092MCQZ4',\n", + " 'B075JN5NX2',\n", + " 'B06Y5XQ6SJ',\n", + " 'B0785QM77V',\n", + " 'B00P0BLZFI',\n", + " 'B08229K7VC',\n", + " 'B09WSVFSGJ',\n", + " 'B0719KWG8H',\n", + " 'B096YFBWGX',\n", + " 'B07FM69672',\n", + " 'B00QZEBH5W',\n", + " 'B00A0RUGPM',\n", + " 'B078WYZK74',\n", + " 'B073SBNLJJ',\n", + " 'B07S8F3LRC',\n", + " 'B01M7UMAUG',\n", + " 'B08393CSHT',\n", + " 'B07FQG965K',\n", + " 'B0778WCBMF',\n", + " 'B007IAE5WY',\n", + " 'B08HH3CH34',\n", + " 'B00J2R8BP8',\n", + " 'B01JIVO8GS',\n", + " 'B07MW1TBSN',\n", + " 'B07KZQDM8Y',\n", + " 'B0B8F6MWFJ',\n", + " 'B09ZKWV5MK',\n", + " 'B08HVRP54L',\n", + " 'B08WPXVK2P',\n", + " 'B09QHM6FKK',\n", + " 'B08N5NDVGH',\n", + " 'B09P144WHW',\n", + " 'B09QT8SLJB',\n", + " 'B092M5K59T',\n", + " 'B099NFX3GJ',\n", + " 'B09C1S6LSV',\n", + " 'B097YYB2GV',\n", + " 'B095CG2ZV1',\n", + " 'B096XDXNY5',\n", + " 'B0841S3FRB',\n", + " 'B083GCHL8R',\n", + " 'B092M1WFTR',\n", + " 'B092D43C8Q',\n", + " 'B08T7GPT1D',\n", + " 'B0919R1CYT',\n", + " 'B08T5RVSD9',\n", + " 'B09473GGM4',\n", + " 'B08T5LG5FT',\n", + " 'B08Z3THTQT',\n", + " 'B08ZVJP6D3',\n", + " 'B08LPGZMQK',\n", + " 'B0925975B7',\n", + " 'B0932WKCMT',\n", + " 'B0929H24R1',\n", + " 'B08MCDB52J',\n", + " 'B08YX4M6T1',\n", + " 'B08GFLMGN2',\n", + " 'B08QRSNJW9',\n", + " 'B08FCV1FQC',\n", + " 'B08YNR839W',\n", + " 'B08YX4HYTK',\n", + " 'B08XZT4FLY',\n", + " 'B08S666KDQ',\n", + " 'B08RS762Z7',\n", + " 'B08R8JQ7NF',\n", + " 'B08VMWZ7N2',\n", + " 'B08NGXBJ4X',\n", + " 'B0881WZVM5',\n", + " 'B08MPP4X5L',\n", + " 'B08QHP717Z',\n", + " 'B08JTNQFZY',\n", + " 'B08RY2LML3',\n", + " 'B08HDLCHXN',\n", + " 'B08MT11QG3',\n", + " 'B08GWKYWMP',\n", + " 'B08N9RT9YD',\n", + " 'B08HGZXLP6',\n", + " 'B08HX5J4P5',\n", + " 'B08PPB3W6H',\n", + " 'B08P7PSMRR',\n", + " 'B08NJ56F9C',\n", + " 'B08LGG9GSG',\n", + " 'B08KT7FCYY',\n", + " 'B08HMLXW65',\n", + " 'B08HMJT41C',\n", + " 'B088DX4Q5K',\n", + " 'B08DKK7KXV',\n", + " 'B08G8B2CQH',\n", + " 'B087B5RJ2P',\n", + " 'B08G83G24X',\n", + " 'B08CZM3GH3',\n", + " 'B086XH7BWW',\n", + " 'B0895XRT9S',\n", + " 'B08C72C56Z',\n", + " 'B07D6KYSJH',\n", + " 'B0829HHW2M',\n", + " 'B07VGBBNTH',\n", + " 'B081ZN3TD5',\n", + " 'B0837K9W6P',\n", + " 'B07LCHCD6Q',\n", + " 'B07KXM94BT',\n", + " 'B07DSC4X3K',\n", + " 'B07DPKZPRH',\n", + " 'B073WQHFXB',\n", + " 'B071NBFSLY',\n", + " 'B01BEYRHBA',\n", + " 'B08CXKJ7TQ',\n", + " 'B08XS4D82F',\n", + " 'B08JP74M51',\n", + " 'B07FP2C8N8',\n", + " 'B09FW4M7G8',\n", + " 'B00F22YKOS',\n", + " 'B07G47T1DV',\n", + " 'B07JCYGJC3',\n", + " 'B00Z5OJPS4',\n", + " 'B00R8LI7ZO',\n", + " 'B096LJJ4K6',\n", + " 'B07D4C2ZZ9',\n", + " 'B07FX94GYX',\n", + " 'B01M1OBRBQ',\n", + " 'B001281404',\n", + " 'B07VM55BYC',\n", + " 'B07L6CFNH6',\n", + " 'B0749FJSN2',\n", + " 'B07KKBCG87',\n", + " 'B07Z5C1KGR',\n", + " 'B075FVH1XS',\n", + " 'B00G7PCKI2',\n", + " 'B07QNX9TJ3',\n", + " 'B0131WQ2G4',\n", + " 'B08T7VB9CP',\n", + " 'B07Q2VZRNX',\n", + " 'B06Y6Q2C7B',\n", + " 'B01695MZ9S',\n", + " 'B000I1CFC2',\n", + " 'B074TG7CVH',\n", + " 'B00OP8NZV4',\n", + " 'B08SBV6Z57',\n", + " 'B086N136NH',\n", + " 'B0872YHQH2',\n", + " 'B08BRS98SF',\n", + " 'B0894LPRN2',\n", + " 'B07KG1TWP5',\n", + " 'B07MN1KJ15',\n", + " 'B08879N2W3',\n", + " 'B07W397QG4',\n", + " 'B086VYKNDF',\n", + " 'B07LCHCD6Q',\n", + " 'B071JMGPTH',\n", + " 'B007VXJK6E',\n", + " 'B094VG2GKR',\n", + " 'B01LXLVB5Q',\n", + " 'B07RD8KL9D',\n", + " 'B01IAX199Y',\n", + " 'B08GC329YR',\n", + " 'B08SLNPD66',\n", + " 'B07N53XT2T',\n", + " 'B07K1LGWYB',\n", + " 'B08PVH18Z6',\n", + " 'B08H4SYXR4',\n", + " 'B08C71WBLC',\n", + " 'B08J3VX89W',\n", + " 'B08H2KSHZZ',\n", + " 'B086S4TF6W',\n", + " 'B08CGFR74H',\n", + " 'B086S4671G',\n", + " 'B07DFNPVSF',\n", + " 'B08BNNNMH5',\n", + " 'B08575Y9V3',\n", + " 'B07P4LLZS6',\n", + " 'B084MFFX5B',\n", + " 'B087LVRGN1',\n", + " 'B07ZS3DKL5',\n", + " 'B085SWH8RG',\n", + " 'B0842Z95FV',\n", + " 'B085C6RN9R',\n", + " 'B07PCLLWHJ',\n", + " 'B083QKQXCH',\n", + " 'B07RM722DH',\n", + " 'B0848VJ18X',\n", + " 'B07Z5BW8WL',\n", + " 'B0046BPTI2',\n", + " 'B07ZG3V78Z',\n", + " 'B07TNSGHVX',\n", + " 'B07XG74ZQ3',\n", + " 'B07XF5F1X9',\n", + " 'B07J1LYVHC',\n", + " 'B07NPWK167',\n", + " 'B019O277A0',\n", + " 'B07QG231LQ',\n", + " 'B07J2QZBTP',\n", + " 'B06Y44MMT6',\n", + " 'B01AWXGD3M',\n", + " 'B078N4PJQY',\n", + " 'B00UVN1H6C',\n", + " 'B01800LTG0',\n", + " 'B00BNARG9O',\n", + " 'B082PW35NV',\n", + " 'B07H8Y5QT2',\n", + " 'B07X4FLT7L',\n", + " 'B08YWJP9PJ',\n", + " 'B01L71F5XW',\n", + " 'B0882TZR45',\n", + " 'B07L44GXXP',\n", + " 'B07927V3SQ',\n", + " 'B074CQC2NG',\n", + " 'B01AS1T9O8',\n", + " 'B09V4FQRLN',\n", + " 'B09QSLMPR5',\n", + " 'B07GRQ1FZ3',\n", + " 'B08CKCV9HD',\n", + " 'B074KD4PX2',\n", + " 'B0BL3HSBZB',\n", + " 'B07WV6JHVM',\n", + " 'B075MPBJDF',\n", + " 'B08C52KD43',\n", + " 'B00PEXDZ7I',\n", + " 'B0756DJ3N9',\n", + " 'B01KZNUGNC',\n", + " 'B074Q2GR3F',\n", + " 'B09K7BZLNX',\n", + " 'B08L6H9B1H',\n", + " 'B07RX25PSS',\n", + " 'B08F2ZJP48',\n", + " 'B0924GT395',\n", + " 'B08RYN11N9',\n", + " 'B09GVHT2D3',\n", + " 'B0868W34QW',\n", + " 'B093VL2JQQ',\n", + " 'B09766LY1D',\n", + " 'B09FDZTZ8Q',\n", + " 'B098JXHFJJ',\n", + " 'B0971V4RL1',\n", + " 'B09BN5TYK5',\n", + " 'B0924896KW',\n", + " 'B09BR43CS5',\n", + " 'B0932BXNKC',\n", + " 'B097Q6DQCD',\n", + " 'B098HXPSV3',\n", + " 'B099NQM7MF',\n", + " 'B08Z2TZTMY',\n", + " 'B0919SX5DN',\n", + " 'B08R2MJJV3',\n", + " 'B08JJC9594',\n", + " 'B093YZRFLW',\n", + " 'B08KFKKPBB',\n", + " 'B08F2RBJJ3',\n", + " 'B0B8DB17VT',\n", + " 'B0881FJSHT',\n", + " 'B01N9LC44Q',\n", + " 'B07DMD8M5T',\n", + " 'B007MB4YW0',\n", + " 'B07TK6647L',\n", + " 'B01MT3CBB6',\n", + " 'B019TSJ9MI',\n", + " 'B00HA72I8S',\n", + " 'B08SPZH2PY',\n", + " 'B087P9SLRC',\n", + " 'B078BXGW8L',\n", + " 'B08L5XMLFZ',\n", + " 'B08B4RN9WN',\n", + " 'B08CZ99R3K',\n", + " 'B08B1PR9C7',\n", + " 'B085M95TX2',\n", + " 'B07VKKLHS6',\n", + " 'B07W3FXQ23',\n", + " 'B07V9V5R48',\n", + " 'B01IPP2036',\n", + " 'B009SNONTO',\n", + " 'B0064QT9MO',\n", + " 'B07QB96HW1',\n", + " 'B01H1RGQGQ',\n", + " 'B00DR75MOM',\n", + " 'B000LX69SI',\n", + " 'B07HH18JK6',\n", + " 'B01BZVADRW',\n", + " 'B07B8CN1MZ',\n", + " 'B0BSR6WK1Q',\n", + " 'B0B1MBRVDS',\n", + " 'B0B4JP5YD9',\n", + " 'B08HVRP54L',\n", + " 'B096YFBWGX',\n", + " 'B0932Z1NM1',\n", + " 'B08SVXBVBW',\n", + " 'B08SG2MBRY',\n", + " 'B08XJWLLKQ',\n", + " 'B08JTNQFZY',\n", + " 'B08L4HTQ3R',\n", + " 'B08LFYMGS5',\n", + " 'B083ST1B9D',\n", + " 'B07YS9W97B',\n", + " 'B08LYT4Q2X',\n", + " 'B08CH5PC9W',\n", + " 'B08M3C6LVS',\n", + " 'B0851QJPZY',\n", + " 'B08BB3P4VQ',\n", + " 'B08DYFZMGJ',\n", + " 'B08CL46XNM',\n", + " 'B07ZS3DKL5',\n", + " 'B087Z9X39L',\n", + " 'B089RLLT5C',\n", + " 'B07TT8JK51',\n", + " 'B09FTLS5G4',\n", + " 'B0171UQIUW',\n", + " 'B089LR2Y1S',\n", + " 'B0BL2Q5PYZ',\n", + " 'B09NKFQL53',\n", + " 'B07N53XT2T',\n", + " 'B083BLZJ9M',\n", + " 'B08LCYPYYJ',\n", + " 'B08M9TJ3NJ',\n", + " 'B08H2KSHZZ',\n", + " 'B001ENX2NY',\n", + " 'B081TG4855',\n", + " 'B07FFBMBP4',\n", + " 'B007IAE5WY',\n", + " 'B00XDB3QTA',\n", + " 'B08QV28D81',\n", + " 'B001VPEFPY',\n", + " 'B06XHHGC49',\n", + " 'B008S59834',\n", + " 'B010L3I6QA',\n", + " 'B00L5HZCPU',\n", + " 'B07X5MHRCZ',\n", + " 'B081QTPRMP',\n", + " 'B07ZDM4RH2',\n", + " 'B000GBID0M',\n", + " 'B08QMNZ61J',\n", + " 'B00UB7D60I',\n", + " 'B01LXDUVYL',\n", + " 'B01DAFX3V4',\n", + " 'B000RHMBSU',\n", + " 'B07BR7FQSW',\n", + " 'B00KOCJEJC',\n", + " 'B0181LWMZ0',\n", + " 'B010HW5HV2',\n", + " 'B07XDTYNMP',\n", + " 'B004X8JLN2',\n", + " 'B0759NDR71',\n", + " 'B00LIAZ8OO',\n", + " 'B094J5PQZP',\n", + " 'B0788GCSVY',\n", + " 'B00756SMTS',\n", + " 'B072N95X6P',\n", + " 'B07731H8YF',\n", + " 'B08TTP42Q1',\n", + " 'B08VMRRCP5',\n", + " 'B00HLJ1DRW',\n", + " 'B07ZHN3QTG',\n", + " 'B07HDZ6Z6V',\n", + " 'B0767M54JB',\n", + " 'B088D2ZCD5',\n", + " 'B00XG58VDY',\n", + " 'B07CQB9H3D',\n", + " 'B00OTJ2W18',\n", + " 'B008C2QZE8',\n", + " 'B00ALUWUBQ',\n", + " 'B0092MCQZ4',\n", + " 'B08393CSHT',\n", + " 'B000NHZSKC',\n", + " 'B004FK48DG',\n", + " 'B07V9QBQTG',\n", + " 'B082Z726F2',\n", + " 'B001DYFIPY',\n", + " 'B01MDLG6II',\n", + " 'B01M6Y49AD',\n", + " 'B07Q69KHDK',\n", + " 'B013VZRLB6',\n", + " 'B008CPAQUE',\n", + " 'B071P6V9JQ',\n", + " 'B0784SJFC1',\n", + " 'B000XTBEYO',\n", + " 'B08MRRNL18',\n", + " 'B082DK8F2L',\n", + " 'B07JHW6VWB',\n", + " 'B08PD5FNFC',\n", + " 'B0002SGSNI',\n", + " 'B072XT9V99',\n", + " 'B01IMEH6GG',\n", + " 'B099FH9Z3D',\n", + " 'B089LN7X8Y',\n", + " 'B06WVGCK8V',\n", + " 'B09XBSDCXP',\n", + " 'B08RRSPNWV',\n", + " 'B0897SY3H2',\n", + " 'B07TJY9TRN',\n", + " 'B087BQ7MS8',\n", + " 'B01I2MU2JQ',\n", + " 'B09GVHT2D3',\n", + " 'B07K7SS8CC',\n", + " 'B07ZYBR6YC',\n", + " 'B07P83R5GT',\n", + " 'B00Z8C3ZNO',\n", + " 'B08NJ5T4VY',\n", + " 'B07PFJNVSY',\n", + " 'B00EEN2HCS',\n", + " 'B08P1YLBVH',\n", + " 'B01N5CJPSX',\n", + " 'B077N1W77M',\n", + " 'B00WUD102M',\n", + " 'B0BNV4WRF3',\n", + " 'B07CPM2897',\n", + " 'B01MSMPDNH',\n", + " 'B075KTSQYS',\n", + " 'B017FYTGHQ',\n", + " 'B0149YNDP6',\n", + " 'B09FK486YF',\n", + " 'B000067E30',\n", + " 'B005FLNLM8',\n", + " 'B00VSEN7F2',\n", + " 'B01H66JESE',\n", + " 'B0168LM53E',\n", + " 'B00U21XOPK',\n", + " 'B01GU38PAC',\n", + " 'B01JOKTHE6',\n", + " 'B01495J3MM',\n", + " 'B07G5P1W9K',\n", + " 'B083TRYQFY',\n", + " 'B00H78IR6W',\n", + " 'B00E2S00ME',\n", + " 'B01LW6VB7M',\n", + " 'B076BTRBTN',\n", + " 'B07VWYNBHJ',\n", + " 'B00PJ8H8WG',\n", + " 'B07CSL21J8',\n", + " 'B0758X2CLZ',\n", + " 'B01N2VTZCC',\n", + " 'B008TGSAFE',\n", + " 'B01GS7QKQQ',\n", + " 'B07TK2PSJF',\n", + " 'B002HEUODA',\n", + " 'B01IAEK0WU',\n", + " 'B0885Y3DNQ',\n", + " 'B06VWPZN56',\n", + " 'B075WF94X4',\n", + " 'B01BX7BY76',\n", + " 'B0107QYW14',\n", + " 'B001V9V71U',\n", + " 'B075JYFWJD',\n", + " 'B015IHU77U',\n", + " 'B014JOL9MA',\n", + " 'B008TGMJQA',\n", + " 'B00XQOR3JS',\n", + " 'B00G9XOZRG',\n", + " 'B017XD9GP6',\n", + " 'B01DUYNJL4',\n", + " 'B004FJZEVM',\n", + " 'B01C714B5E',\n", + " 'B00XP86KXU',\n", + " 'B01DUC1PW6',\n", + " 'B00YVCWUCE',\n", + " 'B07RVN4X51',\n", + " 'B018681Q64',\n", + " 'B013TOAY5O',\n", + " 'B01I066QWG',\n", + " 'B06XHXGSKX',\n", + " 'B082Q58ZTV',\n", + " 'B01N1WM96U',\n", + " 'B00EWUFETQ',\n", + " 'B09NFQ69KT',\n", + " 'B07KG1TWP5',\n", + " 'B07GDQPG12',\n", + " 'B078BC3XDT',\n", + " 'B07W7VK298',\n", + " 'B07FKVTYJX',\n", + " 'B01MTQ5C17',\n", + " 'B01MYPDMEU',\n", + " 'B01CVQALFE',\n", + " 'B01CDEJ1H8',\n", + " 'B0070Z7KME',\n", + " 'B08R5L76V2',\n", + " 'B0721R3XCQ',\n", + " 'B01AONIWZM',\n", + " 'B0865H5R1X',\n", + " 'B071XX8T2N',\n", + " 'B097BN5VXR',\n", + " 'B08SYGY69L',\n", + " 'B00XZ96RNC',\n", + " 'B07XRGFNPV',\n", + " 'B077ZL11DJ',\n", + " 'B01DUYNJL4',\n", + " 'B001DYFIPY',\n", + " 'B092L7Z4GS',\n", + " 'B00SGCP90A',\n", + " 'B07Y1V8PDL',\n", + " 'B009YHP3TS',\n", + " 'B08D9HLNB4',\n", + " 'B01DD1NOZU',\n", + " 'B01D6O4Y12',\n", + " 'B08C2P34JC',\n", + " 'B087BC7GPT',\n", + " 'B00GX1RFEY',\n", + " 'B01KIMMY6C',\n", + " 'B095C6XKKH',\n", + " 'B0769ZGPPN',\n", + " 'B08P4KS91J',\n", + " 'B01MZWUYIE',\n", + " 'B072PY19RB',\n", + " 'B073QSZ7L8',\n", + " 'B08NPTV1DR',\n", + " 'B001V9V71U',\n", + " 'B07PDL9GRS',\n", + " 'B01KDPA96G',\n", + " 'B07Y7X956K',\n", + " 'B07YWRRGSD',\n", + " 'B088NCT267',\n", + " 'B07T3ZQK9W',\n", + " 'B082D9TR1D',\n", + " 'B08B7QTGQH',\n", + " 'B08P5HLJ2Z',\n", + " 'B00FEHM8HM',\n", + " 'B000PKKAGO',\n", + " 'B00JFD29RA',\n", + " 'B01MXLP1T1',\n", + " 'B07577WHPQ',\n", + " 'B005XSZS92',\n", + " 'B00TP82YPM',\n", + " 'B07VVBDDLH',\n", + " 'B003DLQNI6',\n", + " 'B0008GCVU8',\n", + " 'B07CNL2KQP',\n", + " 'B076VQL2Y9',\n", + " 'B07KQ32Z8C',\n", + " 'B0929B8N9L',\n", + " 'B08GMC5ZRY',\n", + " 'B081D2R47W',\n", + " 'B087D7MVHB',\n", + " 'B084XRQLMT',\n", + " 'B07YDLYYP3',\n", + " 'B07H8Y5QT2',\n", + " 'B00LHZC4GA',\n", + " 'B00J4YYA86',\n", + " 'B00RES5TPW',\n", + " 'B001ECZJYU',\n", + " 'B09TWWRFP9',\n", + " 'B07W6LBB2H',\n", + " 'B08KY7VYDS',\n", + " 'B088TFMHJZ',\n", + " 'B087Q3VFZG',\n", + " 'B07HKKFT7T',\n", + " 'B00CXK679S',\n", + " 'B07QY8V5XT',\n", + " 'B00ZQ6S0OQ',\n", + " 'B00QYJ84GI',\n", + " 'B07S411KYQ',\n", + " 'B00CPJIBRI',\n", + " 'B07PWLXFR5',\n", + " 'B07RVBR1BY',\n", + " 'B07CDYN5W8',\n", + " 'B08HGMZZ46',\n", + " 'B07HFVCCHW',\n", + " 'B09C1Y2PM8',\n", + " 'B07L62L82R',\n", + " 'B09HTPJ5PJ',\n", + " 'B0195RD0QY',\n", + " 'B07RM1C9GK',\n", + " 'B005FH2SOO',\n", + " 'B005FH2SOO',\n", + " 'B017CKRWFG',\n", + " 'B074TG7CVH',\n", + " 'B06XNLTVV2',\n", + " 'B002MYXUO0',\n", + " 'B005LFNUF6',\n", + " 'B08BY91SGT',\n", + " 'B08C2GDFYG',\n", + " 'B00KCTER3U',\n", + " 'B00B5WMP8M',\n", + " 'B00I58M2Q4',\n", + " 'B091T4XZKZ',\n", + " 'B07JFRNWDY',\n", + " 'B07WDN4S58',\n", + " 'B01GL4HV64',\n", + " 'B09C1BFKS3',\n", + " 'B01LZ3ZRH1',\n", + " 'B076JLNGS5',\n", + " 'B01AONIWZM',\n", + " 'B00IUI0QFS',\n", + " 'B07YJR8R18',\n", + " 'B075MWNBVG',\n", + " 'B00BS473N4',\n", + " 'B000NIZYIW',\n", + " 'B00E2SF6Q4',\n", + " 'B07PTNZLC6',\n", + " 'B0797ZLSXH',\n", + " 'B08K2WH8LK',\n", + " 'B096G6722H',\n", + " 'B092Z6B3GR',\n", + " 'B08GBP2XKL',\n", + " 'B094MQSRDL',\n", + " 'B08D4X4W22',\n", + " 'B093JD6R98',\n", + " 'B08P5JZYX8',\n", + " 'B08DK4NDM3',\n", + " 'B084WP4XS8',\n", + " 'B08QVJ4NVD',\n", + " 'B07RBSLNFR',\n", + " 'B08RS762Z7',\n", + " 'B084JGNSST',\n", + " 'B08NJ5BTWG',\n", + " 'B08GSMN8DD',\n", + " 'B08MRRNL18',\n", + " 'B07849GHQF',\n", + " 'B08GP7CV1S',\n", + " 'B08D7TLV21',\n", + " 'B079573LDT',\n", + " 'B07DS4GPGX',\n", + " 'B08GSKRQKD',\n", + " 'B083XRBG99',\n", + " 'B08PBDK3WT',\n", + " 'B01N7A5AGF',\n", + " 'B07YS9W97B',\n", + " 'B06ZYWVSZY',\n", + " 'B08F7SCHBZ',\n", + " 'B08L3J4FB9',\n", + " 'B08KNVV18L',\n", + " 'B07YNDWRCB',\n", + " 'B07NPCT6L5',\n", + " 'B086TS3BKQ',\n", + " 'B0868G8GQB',\n", + " 'B07PCGSFGQ',\n", + " 'B07MZT83KK',\n", + " 'B08KGVBW41',\n", + " 'B08GJJ5RV9',\n", + " 'B07VDCD17L',\n", + " 'B073ZR1XLQ',\n", + " 'B08H2KSHZZ',\n", + " 'B01N99J9FD',\n", + " 'B08BB3P4VQ',\n", + " 'B08C37KWRR',\n", + " 'B083BGJ4P9',\n", + " 'B088GWCVVJ',\n", + " 'B087X4B475',\n", + " 'B07RGZNDV4',\n", + " 'B083PQNHF8',\n", + " 'B086SSHLWT',\n", + " 'B0859CYSTM',\n", + " 'B0855L611L',\n", + " 'B07PTQHSQS',\n", + " 'B076DGMQTM',\n", + " 'B07X4J45PS',\n", + " 'B07R3BMYBG',\n", + " 'B0002M5JNY',\n", + " 'B07LCHCD6Q',\n", + " 'B07LBK2YQX',\n", + " 'B07H2TPSZ8',\n", + " 'B07MRFZQVW',\n", + " 'B08JVJ1TDC',\n", + " 'B08S2LYN64',\n", + " 'B07HVRP37G',\n", + " 'B088ZVSLYP',\n", + " 'B0092MCQZ4',\n", + " 'B009WFVG66',\n", + " 'B07YR837T2',\n", + " 'B07K7VD98J',\n", + " 'B08G149DSD',\n", + " 'B086WDP3JW',\n", + " 'B071LLTN9H',\n", + " 'B0811W2VTR',\n", + " 'B0B5Q9JK15',\n", + " 'B00QLBCXL6',\n", + " 'B09XF4N47C',\n", + " 'B09G95ZZR5',\n", + " 'B08MBJ6WPN',\n", + " 'B0998BD871',\n", + " 'B08TGKJKB8',\n", + " 'B099NG1NKV',\n", + " 'B098SYW3L5',\n", + " 'B095XW2M8L',\n", + " 'B08VDTW6V6',\n", + " 'B08XLRCVKY',\n", + " 'B08R3F946X',\n", + " 'B08MF778D7',\n", + " 'B08XJLD2YH',\n", + " 'B08M5CBVWJ',\n", + " 'B07Z548TKH',\n", + " 'B08QYW2FJ2',\n", + " 'B089RZ67T7',\n", + " 'B084ZHP45Y',\n", + " 'B0046BPTI2',\n", + " 'B07YYW1913',\n", + " 'B07X2JL6NH',\n", + " 'B00DTIGWV6',\n", + " 'B01J5ONDPK',\n", + " 'B0BL2Q5PYZ',\n", + " 'B0B4VHNL46',\n", + " 'B09MF28WCD',\n", + " 'B09LLKBZ3S',\n", + " 'B09B4V77YH',\n", + " 'B09H6XWD7C',\n", + " 'B092QKS5WX',\n", + " 'B09CFZK853',\n", + " 'B09D6ZDZN8',\n", + " 'B09GT1GYNR',\n", + " 'B098GMKW8D',\n", + " 'B09571TNVG',\n", + " 'B09DXRXS5L',\n", + " 'B094QK5NSZ',\n", + " 'B09CTMVY68',\n", + " 'B095C1WF44',\n", + " 'B098KCD857',\n", + " 'B099NQM7MF',\n", + " 'B078RC4JXC',\n", + " 'B0936GTH2B',\n", + " 'B095NM2DKG',\n", + " 'B0943YFT9T',\n", + " 'B0912VNQRM',\n", + " 'B0916ZRQDG',\n", + " 'B07T9DC9XK',\n", + " 'B004F87CT0',\n", + " 'B08LG88SWS',\n", + " 'B08DJ1BMHX',\n", + " 'B00XXZZCCU',\n", + " 'B01EUR8IPW',\n", + " 'B08F4ZDVZQ',\n", + " 'B01DCSNO54',\n", + " 'B00LHZC4GA',\n", + " 'B005B6GCN2',\n", + " 'B015SL9P1A',\n", + " 'B01GFEMKES',\n", + " 'B07T23FR6R',\n", + " 'B08ZNLBJ5B',\n", + " 'B0968RPKLF',\n", + " 'B09H52W5LK',\n", + " 'B08NTD1NM1',\n", + " 'B08F4ZDVZQ',\n", + " 'B00FQD0LNW',\n", + " 'B01CURASWA',\n", + " 'B00RIT53JO',\n", + " 'B00K9E0SG8',\n", + " 'B091DF3MPN',\n", + " 'B09758QG59',\n", + " 'B08RYQXJ88',\n", + " 'B08RMZXNH8',\n", + " 'B09473GGM4',\n", + " 'B08HTZKMJ5',\n", + " 'B08QYW2FJ2',\n", + " 'B08L632WH7',\n", + " 'B08G15JBYN',\n", + " 'B01FS5PJNE',\n", + " 'B08Z3J6J56',\n", + " 'B08XJZR3S9',\n", + " 'B0919LJ9WT',\n", + " 'B095H936ZB',\n", + " 'B08CVTNQP1',\n", + " 'B08JZD8HN4',\n", + " 'B07Z548TKH',\n", + " 'B07VQR3W3Z',\n", + " 'B082MDFNZM',\n", + " 'B082TSD9HN',\n", + " 'B07XVNJFNF',\n", + " 'B081M5R5L5',\n", + " 'B0815TNMTL',\n", + " 'B07RWRBF6K',\n", + " 'B082VS3W6R',\n", + " 'B0828W2HXQ',\n", + " 'B07ZYY4QSX',\n", + " 'B07T3WQPRF',\n", + " 'B07YB1CMFT',\n", + " 'B07DPMFTLY',\n", + " 'B000068PBJ',\n", + " 'B073T51X3V',\n", + " 'B08P58XSTQ',\n", + " 'B08NC4378M',\n", + " 'B00KLD1R3K',\n", + " 'B01HCHPY1S',\n", + " 'B003NTFDFM',\n", + " 'B002E4VK40',\n", + " 'B01EUISB9Y',\n", + " 'B018YFOSIW',\n", + " 'B012Q9NGE4',\n", + " 'B0791LZNK9',\n", + " 'B09Y4T49MG',\n", + " 'B07RRR2PJ4',\n", + " 'B07Y2WSGVW',\n", + " 'B0819CS9D7',\n", + " 'B00B0UGRKG',\n", + " 'B012Q9NGE4',\n", + " 'B081JXSP48',\n", + " 'B07WNBZQGT',\n", + " 'B01LZ8SL9N',\n", + " 'B07JJHCQPF',\n", + " 'B077W2RCN7',\n", + " 'B07ZS7K6GZ',\n", + " 'B01HN7GN9E',\n", + " 'B00C0YZBJE',\n", + " 'B08QMK58J6',\n", + " 'B08D38R8GY',\n", + " 'B08D9CK7NM',\n", + " 'B08T5RVSD9',\n", + " 'B08RHMK2GL',\n", + " 'B07JC3GQQM',\n", + " 'B08MFT9ZZ9',\n", + " 'B08BCK4KPS',\n", + " 'B08G5YVHQP',\n", + " 'B08DXLRTSB',\n", + " 'B08C24Q6LB',\n", + " 'B089RLLT5C',\n", + " 'B07DKRK8ZW',\n", + " 'B01EK2F1PC',\n", + " 'B07RZZKXZZ',\n", + " 'B07SQ1LK53',\n", + " 'B0749FXL1T',\n", + " 'B07J2QZBTP',\n", + " 'B076DBLG1K',\n", + " 'B08977LTB1',\n", + " 'B0952LTVVB',\n", + " 'B082WXHH4D',\n", + " 'B07N8JMJGY',\n", + " 'B08P6ZVFDW',\n", + " 'B07XN46M34',\n", + " 'B07T8LY2K5',\n", + " 'B08QZ6H2G4',\n", + " 'B07M5HB65T',\n", + " 'B07V44KKPJ',\n", + " 'B07S5GYK14',\n", + " 'B07D9FTBCR',\n", + " 'B09G3M314N',\n", + " 'B0966F9JZ1',\n", + " 'B01MA3LXIL',\n", + " 'B08RD4MQT6',\n", + " 'B08DRNK7PS',\n", + " 'B089R7S73D',\n", + " 'B08739QVNW',\n", + " 'B087M39FJF',\n", + " 'B087D7MVHB',\n", + " 'B082MTTFZD',\n", + " 'B07NPWK167',\n", + " 'B00TK0VV68',\n", + " 'B07V9MKX7H',\n", + " 'B0047V7MAY',\n", + " 'B00AXXHCLY',\n", + " 'B00915QNQU',\n", + " 'B07H6G9NKG'],\n", + " 'parent_asin': ['B00YQ6X8EO',\n", + " 'B081TJ8YS3',\n", + " 'B097R46CSY',\n", + " 'B09JS339BZ',\n", + " 'B08BZ63GMJ',\n", + " 'B00R8DXL44',\n", + " 'B099DRHW5V',\n", + " 'B08BBQ29N5',\n", + " 'B08P2DZB4X',\n", + " 'B086QY6T7N',\n", + " 'B08DHTJ25J',\n", + " 'B07RBSLNFR',\n", + " 'B07SLFWZKN',\n", + " 'B08JTNQFZY',\n", + " 'B08GLG6W8T',\n", + " 'B08M3C6LVS',\n", + " 'B07GHPCT6T',\n", + " 'B07KG1TWP5',\n", + " 'B07W397QG4',\n", + " 'B07GDQPG12',\n", + " 'B07J3GH1W1',\n", + " 'B01M7UMAUG',\n", + " 'B00JMDPK8S',\n", + " 'B01ETWL5B2',\n", + " 'B07ZJKVVLW',\n", + " 'B082QX2HP6',\n", + " 'B077SRDVG9',\n", + " 'B01AKTGHFW',\n", + " 'B079SMVSYW',\n", + " 'B07K8VTT6M',\n", + " 'B083BDVS36',\n", + " 'B09FP8PP2K',\n", + " 'B0BFR5WF1R',\n", + " 'B00946HGLW',\n", + " 'B082FLP15V',\n", + " 'B0020MKBNW',\n", + " 'B00023J4AW',\n", + " 'B005IYYF5E',\n", + " 'B0B96MFXSJ',\n", + " 'B01M5KNSQN',\n", + " 'B07KDNK11M',\n", + " 'B08DLGCYK8',\n", + " 'B081GCFHPG',\n", + " 'B07H8Z3SMK',\n", + " 'B08C9LZQN4',\n", + " 'B07H281V4V',\n", + " 'B09FF97RHL',\n", + " 'B07Y5QX37B',\n", + " 'B07XYXSYCD',\n", + " 'B07NSR3CKR',\n", + " 'B07CJWG8SP',\n", + " 'B018F28B1Y',\n", + " 'B01HO1ZB7Y',\n", + " 'B0040NQBAG',\n", + " 'B00JNI1DZQ',\n", + " 'B07T2L6JQR',\n", + " 'B095SC4J8T',\n", + " 'B087JNH3NC',\n", + " 'B07SQ8193F',\n", + " 'B09CQ4PXLN',\n", + " 'B08DXDLR3P',\n", + " 'B0875V791H',\n", + " 'B07LBK2YQX',\n", + " 'B07FX94GYX',\n", + " 'B08CXFDDV8',\n", + " 'B015RR870U',\n", + " 'B000OQFVLS',\n", + " 'B00C0YZBJE',\n", + " 'B0B8DZ7H5F',\n", + " 'B0B4JP5YD9',\n", + " 'B0B4JPGX8P',\n", + " 'B09KT4RJG6',\n", + " 'B07KQ32Z8C',\n", + " 'B08PQ6YXSH',\n", + " 'B07W6H8CGT',\n", + " 'B0BTJ6SYKB',\n", + " 'B08KYLTK5H',\n", + " 'B08KWN77LW',\n", + " 'B08HXQ3T9K',\n", + " 'B0B2L218H2',\n", + " 'B0B2L218H2',\n", + " 'B08FRQGYDF',\n", + " 'B08BZ1RHPS',\n", + " 'B085NYYLQ8',\n", + " 'B085WTCBLG',\n", + " 'B088FBNQXW',\n", + " 'B087D7MVHB',\n", + " 'B07PRDZ2BH',\n", + " 'B083TLNBJJ',\n", + " 'B082NKQ4ZT',\n", + " 'B084D86YL8',\n", + " 'B07WNBZQGT',\n", + " 'B07SW7D6ZR',\n", + " 'B07JDD2L3M',\n", + " 'B082MTTFZD',\n", + " 'B07NPWK167',\n", + " 'B07J2QZBTP',\n", + " 'B07N45YN6C',\n", + " 'B077YR3333',\n", + " 'B07FZ5HZLM',\n", + " 'B07KV31WDS',\n", + " 'B07GDQPG12',\n", + " 'B071R2QPF3',\n", + " 'B01KJPFO9W',\n", + " 'B01B6V11UY',\n", + " 'B00GUTPV4A',\n", + " 'B01CO73OIQ',\n", + " 'B00KR4AFJU',\n", + " 'B015ZXMSFQ',\n", + " 'B00KXFD75M',\n", + " 'B010B0S67C',\n", + " 'B00MDKICPK',\n", + " 'B00NNKWDI6',\n", + " 'B00N6WHTRG',\n", + " 'B0943GJDP6',\n", + " 'B0008F6QGO',\n", + " 'B08SWV1X6D',\n", + " 'B08JLXLJGS',\n", + " 'B089K4SV23',\n", + " 'B00KNIECVC',\n", + " 'B088838886',\n", + " 'B01FVUMG28',\n", + " 'B0093EQX6Y',\n", + " 'B00JM1BZUW',\n", + " 'B07KDNK11M',\n", + " 'B08K41B227',\n", + " 'B00EIL38WO',\n", + " 'B003USID1C',\n", + " 'B01N070HWY',\n", + " 'B00G7UFXJA',\n", + " 'B0B7RBK4NJ',\n", + " 'B010B5ZE4U',\n", + " 'B0BP2Y6QY4',\n", + " 'B09JZXY4YR',\n", + " 'B08XJWLLKQ',\n", + " 'B08PLFZB89',\n", + " 'B08KHRF9NY',\n", + " 'B08N6YHQXT',\n", + " 'B08SQ31H8P',\n", + " 'B08LZLBXYT',\n", + " 'B08NPBQR9L',\n", + " 'B08P8BN9BZ',\n", + " 'B08BLX72TP',\n", + " 'B08LYT4Q2X',\n", + " 'B0841WQNNZ',\n", + " 'B087ZQK2G8',\n", + " 'B087Z9X39L',\n", + " 'B07XQKH3RY',\n", + " 'B084ZHP45Y',\n", + " 'B07LCHCD6Q',\n", + " 'B07H3S8WTV',\n", + " 'B071JMGPTH',\n", + " 'B07F8PCLDV',\n", + " 'B07J3GH1W1',\n", + " 'B07FM69672',\n", + " 'B07DSQ3NWM',\n", + " 'B0792Q3T59',\n", + " 'B01NCWHH2W',\n", + " 'B07NGCSZYY',\n", + " 'B07SSLTKHX',\n", + " 'B07G19ZXWB',\n", + " 'B083SCVG16',\n", + " 'B07V6F1TK2',\n", + " 'B01HTO9T2Y',\n", + " 'B0722YW9DZ',\n", + " 'B01MXLP1T1',\n", + " 'B01G5TZ6BM',\n", + " 'B01M1OFZOG',\n", + " 'B075JN5NX2',\n", + " 'B06Y5XQ6SJ',\n", + " 'B0785QM77V',\n", + " 'B00P0BLZFI',\n", + " 'B08229K7VC',\n", + " 'B09WSVFSGJ',\n", + " 'B09X9BG4FC',\n", + " 'B096YFBWGX',\n", + " 'B07FM69672',\n", + " 'B00QZEBH5W',\n", + " 'B00A0RUGPM',\n", + " 'B078WYZK74',\n", + " 'B073SBNLJJ',\n", + " 'B07S8F3LRC',\n", + " 'B01M7UMAUG',\n", + " 'B08393CSHT',\n", + " 'B07FQG965K',\n", + " 'B0778WCBMF',\n", + " 'B085BB7B1M',\n", + " 'B08HH3CH34',\n", + " 'B00J2R8BP8',\n", + " 'B01JIVO8GS',\n", + " 'B07MW1TBSN',\n", + " 'B07KZQDM8Y',\n", + " 'B0B8F6MWFJ',\n", + " 'B09ZKWV5MK',\n", + " 'B08HVRP54L',\n", + " 'B08WPXVK2P',\n", + " 'B0B5X48DZR',\n", + " 'B08N5NDVGH',\n", + " 'B09P144WHW',\n", + " 'B09QT8SLJB',\n", + " 'B092M5K59T',\n", + " 'B09XX4VR4Y',\n", + " 'B09C1S6LSV',\n", + " 'B097YYB2GV',\n", + " 'B095CG2ZV1',\n", + " 'B096XDXNY5',\n", + " 'B0841S3FRB',\n", + " 'B083GCHL8R',\n", + " 'B092M1WFTR',\n", + " 'B092D43C8Q',\n", + " 'B08T7GPT1D',\n", + " 'B0919R1CYT',\n", + " 'B08T5RVSD9',\n", + " 'B09473GGM4',\n", + " 'B08T5LG5FT',\n", + " 'B08Z3THTQT',\n", + " 'B08ZVJP6D3',\n", + " 'B08LPGZMQK',\n", + " 'B0925975B7',\n", + " 'B0932WKCMT',\n", + " 'B0929H24R1',\n", + " 'B08MCDB52J',\n", + " 'B08YX4M6T1',\n", + " 'B08GFLMGN2',\n", + " 'B08QRSNJW9',\n", + " 'B08FCV1FQC',\n", + " 'B08YNR839W',\n", + " 'B08YX4HYTK',\n", + " 'B08XZT4FLY',\n", + " 'B09GNXK3N1',\n", + " 'B08RS762Z7',\n", + " 'B08R8JQ7NF',\n", + " 'B08VMWZ7N2',\n", + " 'B08NGXBJ4X',\n", + " 'B0881WZVM5',\n", + " 'B08MPP4X5L',\n", + " 'B08QHP717Z',\n", + " 'B08JTNQFZY',\n", + " 'B08RY2LML3',\n", + " 'B08HDLCHXN',\n", + " 'B08MT11QG3',\n", + " 'B08HGZXLP6',\n", + " 'B08N9RT9YD',\n", + " 'B08HGZXLP6',\n", + " 'B08HX5J4P5',\n", + " 'B08PPB3W6H',\n", + " 'B08P7PSMRR',\n", + " 'B08NJ56F9C',\n", + " 'B08LGG9GSG',\n", + " 'B08KT7FCYY',\n", + " 'B08HMLXW65',\n", + " 'B08HMJT41C',\n", + " 'B088DX4Q5K',\n", + " 'B08DKK7KXV',\n", + " 'B08G8B2CQH',\n", + " 'B087B5RJ2P',\n", + " 'B08G83G24X',\n", + " 'B08CZM3GH3',\n", + " 'B086XH7BWW',\n", + " 'B0895XRT9S',\n", + " 'B08C72C56Z',\n", + " 'B07D6KYSJH',\n", + " 'B0829HHW2M',\n", + " 'B07VGBBNTH',\n", + " 'B081ZN3TD5',\n", + " 'B0837K9W6P',\n", + " 'B07LCHCD6Q',\n", + " 'B07KXM94BT',\n", + " 'B07DSC4X3K',\n", + " 'B07DPKZPRH',\n", + " 'B073WQHFXB',\n", + " 'B071NBFSLY',\n", + " 'B01BEYRHBA',\n", + " 'B08CXKJ7TQ',\n", + " 'B08XS4D82F',\n", + " 'B08JP74M51',\n", + " 'B07FP2C8N8',\n", + " 'B09FW4M7G8',\n", + " 'B00F22YKOS',\n", + " 'B07G47T1DV',\n", + " 'B07JCYGJC3',\n", + " 'B00Z5OJPS4',\n", + " 'B00R8LI7ZO',\n", + " 'B096LJJ4K6',\n", + " 'B07D4C2ZZ9',\n", + " 'B07FX94GYX',\n", + " 'B01M1OBRBQ',\n", + " 'B001281404',\n", + " 'B07VM55BYC',\n", + " 'B07L6CFNH6',\n", + " 'B0749FJSN2',\n", + " 'B07KKBCG87',\n", + " 'B07Z5C1KGR',\n", + " 'B075FVH1XS',\n", + " 'B00G7PCKI2',\n", + " 'B07QNX9TJ3',\n", + " 'B0131WQ2G4',\n", + " 'B08T7VB9CP',\n", + " 'B07Q2VZRNX',\n", + " 'B06Y6Q2C7B',\n", + " 'B01695MZ9S',\n", + " 'B000I1CFC2',\n", + " 'B074TG7CVH',\n", + " 'B00OP8NZV4',\n", + " 'B08SBV6Z57',\n", + " 'B086N136NH',\n", + " 'B08YJV9YL2',\n", + " 'B08BRS98SF',\n", + " 'B0894LPRN2',\n", + " 'B07KG1TWP5',\n", + " 'B07MN1KJ15',\n", + " 'B08879N2W3',\n", + " 'B07W397QG4',\n", + " 'B086VYKNDF',\n", + " 'B07LCHCD6Q',\n", + " 'B071JMGPTH',\n", + " 'B007VXJK6E',\n", + " 'B094VG2GKR',\n", + " 'B01LXLVB5Q',\n", + " 'B07RD8KL9D',\n", + " 'B01IAX199Y',\n", + " 'B09GNXK3N1',\n", + " 'B08SLNPD66',\n", + " 'B07N53XT2T',\n", + " 'B07K1LGWYB',\n", + " 'B08PVH18Z6',\n", + " 'B08H4SYXR4',\n", + " 'B08C71WBLC',\n", + " 'B08J3VX89W',\n", + " 'B08H2KSHZZ',\n", + " 'B08WCG4JCC',\n", + " 'B08CGFR74H',\n", + " 'B08WCG4JCC',\n", + " 'B07DFNPVSF',\n", + " 'B08BNNNMH5',\n", + " 'B08575Y9V3',\n", + " 'B07P4LLZS6',\n", + " 'B084MFFX5B',\n", + " 'B087LVRGN1',\n", + " 'B07ZS3DKL5',\n", + " 'B085SWH8RG',\n", + " 'B0842Z95FV',\n", + " 'B085C6RN9R',\n", + " 'B07PCLLWHJ',\n", + " 'B083QKQXCH',\n", + " 'B07RM722DH',\n", + " 'B0848VJ18X',\n", + " 'B07Z5BW8WL',\n", + " 'B0046BPTI2',\n", + " 'B07ZG3V78Z',\n", + " 'B07TNSGHVX',\n", + " 'B07XG74ZQ3',\n", + " 'B07XF5F1X9',\n", + " 'B07J1LYVHC',\n", + " 'B07NPWK167',\n", + " 'B019O277A0',\n", + " 'B07QG231LQ',\n", + " 'B07J2QZBTP',\n", + " 'B06Y44MMT6',\n", + " 'B01AWXGD3M',\n", + " 'B078N4PJQY',\n", + " 'B00UVN1H6C',\n", + " 'B01800LTG0',\n", + " 'B00BNARG9O',\n", + " 'B082PW35NV',\n", + " 'B07H8Y5QT2',\n", + " 'B07X4FLT7L',\n", + " 'B08YWJP9PJ',\n", + " 'B01L71F5XW',\n", + " 'B0882TZR45',\n", + " 'B07L44GXXP',\n", + " 'B07927V3SQ',\n", + " 'B074CQC2NG',\n", + " 'B01AS1T9O8',\n", + " 'B09V4FQRLN',\n", + " 'B09QSLMPR5',\n", + " 'B07GRQ1FZ3',\n", + " 'B08CKCV9HD',\n", + " 'B074KD4PX2',\n", + " 'B0BL3HSBZB',\n", + " 'B07WV6JHVM',\n", + " 'B075MPBJDF',\n", + " 'B0B2L218H2',\n", + " 'B079JPNPF3',\n", + " 'B0756DJ3N9',\n", + " 'B01KZNUGNC',\n", + " 'B07K5MGRZS',\n", + " 'B0974GWS7Z',\n", + " 'B08L6H9B1H',\n", + " 'B07RX25PSS',\n", + " 'B08F2ZJP48',\n", + " 'B0924GT395',\n", + " 'B08RYN11N9',\n", + " 'B09GVHT2D3',\n", + " 'B0868W34QW',\n", + " 'B093VL2JQQ',\n", + " 'B09766LY1D',\n", + " 'B09FDZTZ8Q',\n", + " 'B098JXHFJJ',\n", + " 'B0971V4RL1',\n", + " 'B09BN5TYK5',\n", + " 'B0924896KW',\n", + " 'B09BR43CS5',\n", + " 'B0932BXNKC',\n", + " 'B097Q6DQCD',\n", + " 'B098HXPSV3',\n", + " 'B099NQM7MF',\n", + " 'B08Z2TZTMY',\n", + " 'B0919SX5DN',\n", + " 'B08R2MJJV3',\n", + " 'B08JJC9594',\n", + " 'B093YZRFLW',\n", + " 'B08KFKKPBB',\n", + " 'B08F2RBJJ3',\n", + " 'B0B8DB17VT',\n", + " 'B0881FJSHT',\n", + " 'B09Q3X5YWR',\n", + " 'B07DMD8M5T',\n", + " 'B007MB4YW0',\n", + " 'B07TK6647L',\n", + " 'B01MT3CBB6',\n", + " 'B019TSJ9MI',\n", + " 'B00HA72I8S',\n", + " 'B08SQKBBP8',\n", + " 'B087P9SLRC',\n", + " 'B078BXGW8L',\n", + " 'B08L5XMLFZ',\n", + " 'B08B4RN9WN',\n", + " 'B08CZ99R3K',\n", + " 'B08B1PR9C7',\n", + " 'B085M95TX2',\n", + " 'B07VKKLHS6',\n", + " 'B07W3FXQ23',\n", + " 'B07V9V5R48',\n", + " 'B01IPP2036',\n", + " 'B009SNONTO',\n", + " 'B0064QT9MO',\n", + " 'B07QB96HW1',\n", + " 'B01H1RGQGQ',\n", + " 'B00DR75MOM',\n", + " 'B000LX69SI',\n", + " 'B07HH18JK6',\n", + " 'B01BZVADRW',\n", + " 'B07B8CN1MZ',\n", + " 'B0BXB4J297',\n", + " 'B0B1MBRVDS',\n", + " 'B0B4JP5YD9',\n", + " 'B08HVRP54L',\n", + " 'B096YFBWGX',\n", + " 'B0932Z1NM1',\n", + " 'B08SVXBVBW',\n", + " 'B08SG2MBRY',\n", + " 'B08XJWLLKQ',\n", + " 'B08JTNQFZY',\n", + " 'B08L4HTQ3R',\n", + " 'B08LFYMGS5',\n", + " 'B083ST1B9D',\n", + " 'B07YS9W97B',\n", + " 'B08LYT4Q2X',\n", + " 'B08CH5PC9W',\n", + " 'B08M3C6LVS',\n", + " 'B0851QJPZY',\n", + " 'B08BB3P4VQ',\n", + " 'B08DYFZMGJ',\n", + " 'B08CL46XNM',\n", + " 'B07ZS3DKL5',\n", + " 'B087Z9X39L',\n", + " 'B089RLLT5C',\n", + " 'B07TT8JK51',\n", + " 'B09FTLS5G4',\n", + " 'B0171UQIUW',\n", + " 'B089LR2Y1S',\n", + " 'B0BL2Q5PYZ',\n", + " 'B09NKFQL53',\n", + " 'B07N53XT2T',\n", + " 'B083BLZJ9M',\n", + " 'B08LCYPYYJ',\n", + " 'B08M9TJ3NJ',\n", + " 'B08H2KSHZZ',\n", + " 'B001ENX2NY',\n", + " 'B081TG4855',\n", + " 'B07FFBMBP4',\n", + " 'B085BB7B1M',\n", + " 'B00XDB3QTA',\n", + " 'B08QV28D81',\n", + " 'B001VPEFPY',\n", + " 'B06XHHGC49',\n", + " 'B008S59834',\n", + " 'B010L3I6QA',\n", + " 'B00L5HZCPU',\n", + " 'B07X5MHRCZ',\n", + " 'B081QTPRMP',\n", + " 'B0888TZ9W6',\n", + " 'B000GBID0M',\n", + " 'B08QMNZ61J',\n", + " 'B00UB7D60I',\n", + " 'B01LXDUVYL',\n", + " 'B01DAFX3V4',\n", + " 'B000RHMBSU',\n", + " 'B07BR7FQSW',\n", + " 'B00KOCJEJC',\n", + " 'B0181LWMZ0',\n", + " 'B010HW5HV2',\n", + " 'B07XDTYNMP',\n", + " 'B004X8JLN2',\n", + " 'B0759NDR71',\n", + " 'B00LIAZ8OO',\n", + " 'B094J5PQZP',\n", + " 'B0788GCSVY',\n", + " 'B00756SMTS',\n", + " 'B072N95X6P',\n", + " 'B07731H8YF',\n", + " 'B08TTP42Q1',\n", + " 'B08VMRRCP5',\n", + " 'B00HLJ1DRW',\n", + " 'B07ZHN3QTG',\n", + " 'B07HDZ6Z6V',\n", + " 'B0767M54JB',\n", + " 'B088D2ZCD5',\n", + " 'B00XG58VDY',\n", + " 'B07CQB9H3D',\n", + " 'B00OTJ2W18',\n", + " 'B008C2QYPI',\n", + " 'B00ALUWUBQ',\n", + " 'B01M1OFZOG',\n", + " 'B08393CSHT',\n", + " 'B000NHZSKC',\n", + " 'B004FK48DG',\n", + " 'B07V9QBQTG',\n", + " 'B082Z726F2',\n", + " 'B07Y6WBGQQ',\n", + " 'B01MDLG6II',\n", + " 'B01M6Y49AD',\n", + " 'B07Q69KHDK',\n", + " 'B013VZRLB6',\n", + " 'B008CPAQUE',\n", + " 'B071P6V9JQ',\n", + " 'B0784SJFC1',\n", + " 'B086H4C8QB',\n", + " 'B08MRRNL18',\n", + " 'B082DK8F2L',\n", + " 'B07JHW6VWB',\n", + " 'B08PD5FNFC',\n", + " 'B0002SGSNI',\n", + " 'B0BMWQQR9W',\n", + " 'B01IMEH6GG',\n", + " 'B099FH9Z3D',\n", + " 'B089LN7X8Y',\n", + " 'B06WVGCK8V',\n", + " 'B09XBSDCXP',\n", + " 'B08RRSPNWV',\n", + " 'B0897SY3H2',\n", + " 'B07TJY9TRN',\n", + " 'B087BQ7MS8',\n", + " 'B01I2MU2JQ',\n", + " 'B09GVHT2D3',\n", + " 'B07K7SS8CC',\n", + " 'B07ZYBR6YC',\n", + " 'B07P83R5GT',\n", + " 'B00Z8C3ZNO',\n", + " 'B08NJ5T4VY',\n", + " 'B07PFJNVSY',\n", + " 'B0BM4GX6TT',\n", + " 'B08P1YLBVH',\n", + " 'B01N5CJPSX',\n", + " 'B077N1W77M',\n", + " 'B00WUD102M',\n", + " 'B0BNV4WRF3',\n", + " 'B07CPM2897',\n", + " 'B01MSMPDNH',\n", + " 'B075KTSQYS',\n", + " 'B017FYTGHQ',\n", + " 'B0149YNDP6',\n", + " 'B09FK486YF',\n", + " 'B000067E30',\n", + " 'B005FLNLM8',\n", + " 'B09W66MSPX',\n", + " 'B01H66JESE',\n", + " 'B0168LM53E',\n", + " 'B00U21XOPK',\n", + " 'B01GU38PAC',\n", + " 'B01JOKTHE6',\n", + " 'B01495J3MM',\n", + " 'B07G5P1W9K',\n", + " 'B083TRYQFY',\n", + " 'B00H78IR6W',\n", + " 'B00E2S00ME',\n", + " 'B01LW6VB7M',\n", + " 'B076BTRBTN',\n", + " 'B07VWYNBHJ',\n", + " 'B073TBC4TS',\n", + " 'B07CSL21J8',\n", + " 'B0758X2CLZ',\n", + " 'B01N2VTZCC',\n", + " 'B008TGSAFE',\n", + " 'B01GS7QKQQ',\n", + " 'B07TK15BQQ',\n", + " 'B002HEUODA',\n", + " 'B086H4C8QB',\n", + " 'B0885Y3DNQ',\n", + " 'B06VWPZN56',\n", + " 'B075WF94X4',\n", + " 'B01BX7BY76',\n", + " 'B0107QYW14',\n", + " 'B001V9V71U',\n", + " 'B0BDHS9H7J',\n", + " 'B0881Y9BLS',\n", + " 'B014JOL9MA',\n", + " 'B008TGMJQA',\n", + " 'B00XQOR3JS',\n", + " 'B00G9XOZRG',\n", + " 'B017XD9GP6',\n", + " 'B01DUYNJL4',\n", + " 'B004FJZEVM',\n", + " 'B01C714B5E',\n", + " 'B00XP86KXU',\n", + " 'B01DUC1PW6',\n", + " 'B00YVCWUCE',\n", + " 'B07RVN4X51',\n", + " 'B018681Q64',\n", + " 'B013TOAY5O',\n", + " 'B09FFQT1KK',\n", + " 'B06XHXGSKX',\n", + " 'B082Q58ZTV',\n", + " 'B01N1WM96U',\n", + " 'B00EWUFETQ',\n", + " 'B09NFQ69KT',\n", + " 'B07KG1TWP5',\n", + " 'B07GDQPG12',\n", + " 'B08FYBSFPR',\n", + " 'B09W66MSPX',\n", + " 'B07FKVTYJX',\n", + " 'B01MTQ5C17',\n", + " 'B01MYPDMEU',\n", + " 'B01CVQALFE',\n", + " 'B01CDEJ1H8',\n", + " 'B00J7QCNDU',\n", + " 'B08R5L76V2',\n", + " 'B0721R3XCQ',\n", + " 'B01AONIWZM',\n", + " 'B0865H5R1X',\n", + " 'B071XX8T2N',\n", + " 'B097BN5VXR',\n", + " 'B08SYGY69L',\n", + " 'B00XZ96RNC',\n", + " 'B07XRGFNPV',\n", + " 'B077ZL11DJ',\n", + " 'B01DUYNJL4',\n", + " 'B07Y6WBGQQ',\n", + " 'B092L7Z4GS',\n", + " 'B00SGCP90A',\n", + " 'B07Y1V8PDL',\n", + " 'B009YHP3TS',\n", + " 'B08D9HLNB4',\n", + " 'B01DD1NOZU',\n", + " 'B01DD1NOZU',\n", + " 'B08C2P34JC',\n", + " 'B087BC7GPT',\n", + " 'B00GX1RFEY',\n", + " 'B01KIMMY6C',\n", + " 'B095C6XKKH',\n", + " 'B0769ZGPPN',\n", + " 'B08P4KS91J',\n", + " 'B01MZWUYIE',\n", + " 'B072PY19RB',\n", + " 'B073QSZ7L8',\n", + " 'B08NPTV1DR',\n", + " 'B001V9V71U',\n", + " 'B07PDL9GRS',\n", + " 'B01KDPA96G',\n", + " 'B07Y7X956K',\n", + " 'B07YWRRGSD',\n", + " 'B088NCT267',\n", + " 'B07T3ZQK9W',\n", + " 'B082D9TR1D',\n", + " 'B08B7QTGQH',\n", + " 'B08P5HLJ2Z',\n", + " 'B00FEHM8HM',\n", + " 'B000PKKAGO',\n", + " 'B00JFD29RA',\n", + " 'B01MXLP1T1',\n", + " 'B0B96MFXSJ',\n", + " 'B005XSZS92',\n", + " 'B00TP82YPM',\n", + " 'B07VVBDDLH',\n", + " 'B003DLQNI6',\n", + " 'B07FMH13N6',\n", + " 'B07CNL2KQP',\n", + " 'B076VQL2Y9',\n", + " 'B07KQ32Z8C',\n", + " 'B0929B8N9L',\n", + " 'B08GMC5ZRY',\n", + " 'B081D2R47W',\n", + " 'B087D7MVHB',\n", + " 'B0914JBBTV',\n", + " 'B07YDLYYP3',\n", + " 'B07H8Y5QT2',\n", + " 'B00LHZC4GA',\n", + " 'B00J4YYA86',\n", + " 'B00RES5TPW',\n", + " 'B001ECZJYU',\n", + " 'B09TWWRFP9',\n", + " 'B07W6LBB2H',\n", + " 'B08KY7VYDS',\n", + " 'B088TFMHJZ',\n", + " 'B087Q3VFZG',\n", + " 'B07HKKFT7T',\n", + " 'B00CXK679S',\n", + " 'B07QY8V5XT',\n", + " 'B00ZQ6S0OQ',\n", + " 'B00QYJ84GI',\n", + " 'B07S411KYQ',\n", + " 'B07NTQNDK8',\n", + " 'B07PWLXFR5',\n", + " 'B07RVBR1BY',\n", + " 'B07CDYN5W8',\n", + " 'B08HGMZZ46',\n", + " 'B07HFVCCHW',\n", + " 'B09C1Y2PM8',\n", + " 'B07L62L82R',\n", + " 'B09HTPJ5PJ',\n", + " 'B0195RD0QY',\n", + " 'B07RM1C9GK',\n", + " 'B096LHP8WQ',\n", + " 'B096LHP8WQ',\n", + " 'B017CKRWFG',\n", + " 'B074TG7CVH',\n", + " 'B06XNLTVV2',\n", + " 'B002MYXUO0',\n", + " 'B005LFNUF6',\n", + " 'B08BY91SGT',\n", + " 'B08C2GDFYG',\n", + " 'B00KCTER3U',\n", + " 'B00B5WMP8M',\n", + " 'B00I58M2Q4',\n", + " 'B091T4XZKZ',\n", + " 'B07JFRNWDY',\n", + " 'B07WDN4S58',\n", + " 'B01GL4HV64',\n", + " 'B09C1BFKS3',\n", + " 'B01LZ3ZRH1',\n", + " 'B076JLNGS5',\n", + " 'B01AONIWZM',\n", + " 'B00IUI0QFS',\n", + " 'B07YJR8R18',\n", + " 'B075MWNBVG',\n", + " 'B00BS473N4',\n", + " 'B000NIZYIW',\n", + " 'B00E2SF6Q4',\n", + " 'B07PTNZLC6',\n", + " 'B0797ZLSXH',\n", + " 'B08K2WH8LK',\n", + " 'B096G6722H',\n", + " 'B092Z6B3GR',\n", + " 'B09GNXK3N1',\n", + " 'B094MQSRDL',\n", + " 'B08D4X4W22',\n", + " 'B0BQQ5L942',\n", + " 'B08P5JZYX8',\n", + " 'B08DK4NDM3',\n", + " 'B084WP4XS8',\n", + " 'B08QVJ4NVD',\n", + " 'B07RBSLNFR',\n", + " 'B08RS762Z7',\n", + " 'B084JGNSST',\n", + " 'B08NJ5BTWG',\n", + " 'B08GSMN8DD',\n", + " 'B08MRRNL18',\n", + " 'B07849GHQF',\n", + " 'B08GP7CV1S',\n", + " 'B08D7TLV21',\n", + " 'B079573LDT',\n", + " 'B07DS4GPGX',\n", + " 'B08GSKRQKD',\n", + " 'B083XRBG99',\n", + " 'B08PBDK3WT',\n", + " 'B01N7A5AGF',\n", + " 'B07YS9W97B',\n", + " 'B06ZYWVSZY',\n", + " 'B08JCX3DL7',\n", + " 'B08L3J4FB9',\n", + " 'B08KNVV18L',\n", + " 'B07YNDWRCB',\n", + " 'B07NPCT6L5',\n", + " 'B086TS3BKQ',\n", + " 'B0868G8GQB',\n", + " 'B07PCGSFGQ',\n", + " 'B07MZT83KK',\n", + " 'B08KGVBW41',\n", + " 'B08GJJ5RV9',\n", + " 'B07VDCD17L',\n", + " 'B073ZR1XLQ',\n", + " 'B08H2KSHZZ',\n", + " 'B01N99J9FD',\n", + " 'B08BB3P4VQ',\n", + " 'B08C37KWRR',\n", + " 'B083BGJ4P9',\n", + " 'B088GWCVVJ',\n", + " 'B087X4B475',\n", + " 'B07RGZNDV4',\n", + " 'B083PQNHF8',\n", + " 'B086SSHLWT',\n", + " 'B0859CYSTM',\n", + " 'B0855L611L',\n", + " 'B07PTQHSQS',\n", + " 'B076DGMQTM',\n", + " 'B07X4J45PS',\n", + " 'B07R3BMYBG',\n", + " 'B0002M5JNY',\n", + " 'B07LCHCD6Q',\n", + " 'B07LBK2YQX',\n", + " 'B07H2TPSZ8',\n", + " 'B07MRFZQVW',\n", + " 'B08JVJ1TDC',\n", + " 'B08S2LYN64',\n", + " 'B07HVRP37G',\n", + " 'B088ZVSLYP',\n", + " 'B01M1OFZOG',\n", + " 'B009WFVG66',\n", + " 'B07YR837T2',\n", + " 'B0BV1FPZY6',\n", + " 'B08G149DSD',\n", + " 'B086WDP3JW',\n", + " 'B071LLTN9H',\n", + " 'B0811W2VTR',\n", + " 'B0B5Q9JK15',\n", + " 'B00QLBCXL6',\n", + " 'B09XF4WD3V',\n", + " 'B09G95ZZR5',\n", + " 'B08MBJ6WPN',\n", + " 'B0998BD871',\n", + " 'B08TGKJKB8',\n", + " 'B099NG1NKV',\n", + " 'B098SYW3L5',\n", + " 'B095XW2M8L',\n", + " 'B08VDTW6V6',\n", + " 'B08XLRCVKY',\n", + " 'B08R3F946X',\n", + " 'B08MF778D7',\n", + " 'B08XJLD2YH',\n", + " 'B08M5CBVWJ',\n", + " 'B07Z548TKH',\n", + " 'B08QYW2FJ2',\n", + " 'B089RZ67T7',\n", + " 'B084ZHP45Y',\n", + " 'B0046BPTI2',\n", + " 'B07YYW1913',\n", + " 'B07X2JL6NH',\n", + " 'B0B7MCJ618',\n", + " 'B01J5ONDPK',\n", + " 'B0BL2Q5PYZ',\n", + " 'B0B4VHNL46',\n", + " 'B09MF28WCD',\n", + " 'B09LLKBZ3S',\n", + " 'B09B4V77YH',\n", + " 'B09H6XWD7C',\n", + " 'B092QKS5WX',\n", + " 'B09CFZK853',\n", + " 'B09D6ZDZN8',\n", + " 'B09GT1GYNR',\n", + " 'B098GMKW8D',\n", + " 'B09571TNVG',\n", + " 'B09DXR7QJY',\n", + " 'B094QK5NSZ',\n", + " 'B09CTMVY68',\n", + " 'B095C1WF44',\n", + " 'B098KCD857',\n", + " 'B099NQM7MF',\n", + " 'B078RC4JXC',\n", + " 'B0936GTH2B',\n", + " 'B095NM2DKG',\n", + " 'B0943Y3Z8N',\n", + " 'B0912VNQRM',\n", + " 'B0916ZRQDG',\n", + " 'B07T9DC9XK',\n", + " 'B004F87CT0',\n", + " 'B08LG88SWS',\n", + " 'B08DJ1BMHX',\n", + " 'B00XXZZCCU',\n", + " 'B01EUR8IPW',\n", + " 'B08F4ZDVZQ',\n", + " 'B01DCSNO54',\n", + " 'B00LHZC4GA',\n", + " 'B005B6GCN2',\n", + " 'B015SL9P1A',\n", + " 'B01GFEMKES',\n", + " 'B07T23FR6R',\n", + " 'B08ZNLBJ5B',\n", + " 'B0968RPKLF',\n", + " 'B09H52W5LK',\n", + " 'B08NTD1NM1',\n", + " 'B08F4ZDVZQ',\n", + " 'B00FQD0LNW',\n", + " 'B01CURASWA',\n", + " 'B00RIT53JO',\n", + " 'B00K9E0SG8',\n", + " 'B091DF3MPN',\n", + " 'B09758QG59',\n", + " 'B08RYQXJ88',\n", + " 'B08RMZXNH8',\n", + " 'B09473GGM4',\n", + " 'B08HTZKMJ5',\n", + " 'B08QYW2FJ2',\n", + " 'B08L632WH7',\n", + " 'B08G15JBYN',\n", + " 'B01FS5PJNE',\n", + " 'B08Z3J6J56',\n", + " 'B08XJZR3S9',\n", + " 'B0919LJ9WT',\n", + " 'B095H936ZB',\n", + " 'B08CVTNQP1',\n", + " 'B08JZD8HN4',\n", + " 'B07Z548TKH',\n", + " 'B07VQR3W3Z',\n", + " 'B082MDFNZM',\n", + " 'B082TSD9HN',\n", + " 'B07XVNJFNF',\n", + " 'B081M5R5L5',\n", + " 'B0815TNMTL',\n", + " 'B07RWRBF6K',\n", + " 'B082VS3W6R',\n", + " 'B0828W2HXQ',\n", + " 'B07ZYY4QSX',\n", + " 'B07T3WQPRF',\n", + " 'B07YB1CMFT',\n", + " 'B07DPMFTLY',\n", + " 'B000068PBJ',\n", + " 'B073T51X3V',\n", + " 'B08P58XSTQ',\n", + " 'B08NC4378M',\n", + " 'B0C3LVTX2V',\n", + " 'B01HCHPY1S',\n", + " 'B003NTFDFM',\n", + " 'B002E4VK40',\n", + " 'B01EUISB9Y',\n", + " 'B018YFOSIW',\n", + " 'B012Q9NGE4',\n", + " 'B0791LZNK9',\n", + " 'B09Y4T49MG',\n", + " 'B07RRR2PJ4',\n", + " 'B07Y2WSGVW',\n", + " 'B0819CS9D7',\n", + " 'B00B0UGRKG',\n", + " 'B012Q9NGE4',\n", + " 'B081JXSP48',\n", + " 'B07WNBZQGT',\n", + " 'B01LZ8SL9N',\n", + " 'B07JJHCQPF',\n", + " 'B077W2RCN7',\n", + " 'B07ZS7K6GZ',\n", + " 'B01HN7GN9E',\n", + " 'B00C0YZBJE',\n", + " 'B08QMK58J6',\n", + " 'B08D38R8GY',\n", + " 'B08D9CK7NM',\n", + " 'B08T5RVSD9',\n", + " 'B08RHMK2GL',\n", + " 'B07JC3GQQM',\n", + " 'B08MFT9ZZ9',\n", + " 'B08BCK4KPS',\n", + " 'B08G5YVHQP',\n", + " 'B08DXLRTSB',\n", + " 'B08C24Q6LB',\n", + " 'B089RLLT5C',\n", + " 'B07DKRK8ZW',\n", + " 'B01EK2F1PC',\n", + " 'B07RZZKXZZ',\n", + " 'B07SQ1LK53',\n", + " 'B0749FXL1T',\n", + " 'B07J2QZBTP',\n", + " 'B076DBLG1K',\n", + " 'B08977LTB1',\n", + " 'B0952LTVVB',\n", + " 'B082WXHH4D',\n", + " 'B07N8JMJGY',\n", + " 'B08P6ZVFDW',\n", + " 'B07XN46M34',\n", + " 'B07T8LY2K5',\n", + " 'B08QZ6H2G4',\n", + " 'B07M5HB65T',\n", + " 'B07V44KKPJ',\n", + " 'B07S5GYK14',\n", + " 'B07D9FTBCR',\n", + " 'B09G3KBK7Y',\n", + " 'B0966F9JZ1',\n", + " 'B01MA3LXIL',\n", + " 'B08RD4MQT6',\n", + " 'B08DRNK7PS',\n", + " 'B089R7S73D',\n", + " 'B0BTJ6SYKB',\n", + " 'B087M39FJF',\n", + " 'B087D7MVHB',\n", + " 'B082MTTFZD',\n", + " 'B07NPWK167',\n", + " 'B00TK0VV68',\n", + " 'B07V9MKX7H',\n", + " 'B0047V7MAY',\n", + " 'B00AXXHCLY',\n", + " 'B00915QNQU',\n", + " 'B07H6G9NKG'],\n", + " 'user_id': ['AGKHLEW2SOWHNMFQIJGBECAF7INQ',\n", + " 'AGKHLEW2SOWHNMFQIJGBECAF7INQ',\n", + " 'AE74DYR3QUGVPZJ3P7RFWBGIX7XQ',\n", + " 'AFQLNQNQYFWQZPJQZS6V3NZU4QBQ',\n", + " 'AFQLNQNQYFWQZPJQZS6V3NZU4QBQ',\n", + " 'AGMJ3EMDVL6OWBJF7CA5RGJLXN5A',\n", + " 'AHREXOGQPZDA6354MHH4ETSF3MCQ',\n", + " 'AEYORY2AVPMCPDV57CE337YU5LXA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AFSKPY37N3C43SOI5IEXEK5JSIYA',\n", + " 'AG35BKPUEUMX7LV5YLOQ5YCQ3GOA',\n", + " 'AHPUT3ITXCHQJO7OMF74LEMYHIVA',\n", + " 'AHGAOIZVODNHYMNCBV4DECZH42UQ',\n", + " 'AHGAOIZVODNHYMNCBV4DECZH42UQ',\n", + " 'AHGAOIZVODNHYMNCBV4DECZH42UQ',\n", + " 'AFGEM6BXCYHUILEOA3P2ZYBEF2TA',\n", + " 'AGC3Q6IXOVLTTDMS4Q55FPYUF6FQ',\n", + " 'AHZ6XMOLEWA67S3TX7IWEXXGWSOA',\n", + " 'AH6ZNRRCEEWR6P34CNLQ2LRLUU3Q',\n", + " 'AFZUK3MTBIBEDQOPAK3OATUOUKLA',\n", + " 'AFZUK3MTBIBEDQOPAK3OATUOUKLA',\n", + " 'AFZUK3MTBIBEDQOPAK3OATUOUKLA',\n", + " 'AFZUK3MTBIBEDQOPAK3OATUOUKLA',\n", + " 'AFKNVFEXRGUGJAGMENCOWLVDYVCQ',\n", + " 'AFKNVFEXRGUGJAGMENCOWLVDYVCQ',\n", + " 'AHFURURV4H35BXUUTXYMJYA36CTQ',\n", + " 'AFETVW7S5M4LVJ7GTWPCKT7S3YBQ',\n", + " 'AGF42GID7QWDCNFTJRCTMKAITJJA',\n", + " 'AGF42GID7QWDCNFTJRCTMKAITJJA',\n", + " 'AE5DIA2HDWBPNGBO2FXN2PF4NQJA',\n", + " 'AF2FTNKCY6XY67BKBUO4BNJRZ4XQ',\n", + " 'AHEQRHKGEACLR3RSXRQ7TUIXZGSQ',\n", + " 'AHW7W34BLHHC4AYM4TPMLA2SWMMA',\n", + " 'AGVVUU3QRQBHNASSGI5YQLPYOI2Q',\n", + " 'AGG3LLILZEGKCA4SAS4Q7X2Y7ISQ',\n", + " 'AGG3LLILZEGKCA4SAS4Q7X2Y7ISQ',\n", + " 'AH4O5W3EM4CKQGHMBVTSPCJRYF7Q',\n", + " 'AH4O5W3EM4CKQGHMBVTSPCJRYF7Q',\n", + " 'AH4O5W3EM4CKQGHMBVTSPCJRYF7Q',\n", + " 'AFPBVAEV3FCQOHKJJGAKQLZLTCZQ',\n", + " 'AHSAUHUTLVNKJ72GUIPGI5XZH6ZA',\n", + " 'AHSAUHUTLVNKJ72GUIPGI5XZH6ZA',\n", + " 'AEEM2QIBMUUXEAJIEQH2WT2KNZZA',\n", + " 'AH4CGRSYSW5CWLRGQYRZKNJBUPAA',\n", + " 'AH4CGRSYSW5CWLRGQYRZKNJBUPAA',\n", + " 'AH4CGRSYSW5CWLRGQYRZKNJBUPAA',\n", + " 'AHATA6X6MYTC3VNBFJ3WIYVK257A',\n", + " 'AHATA6X6MYTC3VNBFJ3WIYVK257A',\n", + " 'AHATA6X6MYTC3VNBFJ3WIYVK257A',\n", + " 'AHATA6X6MYTC3VNBFJ3WIYVK257A',\n", + " 'AHATA6X6MYTC3VNBFJ3WIYVK257A',\n", + " 'AFA26DYXVLJYTYZ3KET77GE27N2A',\n", + " 'AFA26DYXVLJYTYZ3KET77GE27N2A',\n", + " 'AFA26DYXVLJYTYZ3KET77GE27N2A',\n", + " 'AFLGWVMNAKFSOPJNKKLYHP2F2IMQ',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AHV6QCNBJNSGLATP56JAWJ3C4G2A',\n", + " 'AF3IELI63FDNLEAGV2I6KYJ2LXFA',\n", + " 'AEITH2MBDGMCSAZSBNAYOEBOJXFA',\n", + " 'AGYBOBPV47L6FRILNSZ7S6XFLPFA',\n", + " 'AEVLPO2NHUQOLLCLFH75UHGJPMLA',\n", + " 'AEWTKEIDMSOZ7Z3MOOEIXYPYUCCQ',\n", + " 'AH64T2MRMNF76UENPWCIMMCYTSZA',\n", + " 'AG7WKTZINOFIXMZJYIPKIB7PV7NQ',\n", + " 'AG7WKTZINOFIXMZJYIPKIB7PV7NQ',\n", + " 'AG7WKTZINOFIXMZJYIPKIB7PV7NQ',\n", + " 'AEHVSZ72XXI4SU6XUNXMJAXUYN6Q',\n", + " 'AEHWUHNTB5FX32HJ7UBOZ2WWUX3Q',\n", + " 'AFXPXKJ5MAQPX5NIXMU5C4ISAIGA',\n", + " 'AGPOZ62Q3ULTH7RLBK4BIJ75T2KQ',\n", + " 'AGPOZ62Q3ULTH7RLBK4BIJ75T2KQ',\n", + " 'AGTHQ6ANUEV7VOOVAEFWVMFIILUA',\n", + " 'AGTHQ6ANUEV7VOOVAEFWVMFIILUA',\n", + " 'AEZ26WGWJ3EOQ4KWSHG77HJAG4EA',\n", + " 'AGCCFLGNMV6ABDOO4O6SUJW65ICA',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AFJBKPK5W56XWSNPQU2WW66ISWYQ',\n", + " 'AGQKBA5POXDOUO4U43YF2LNEZPLA',\n", + " 'AGQKBA5POXDOUO4U43YF2LNEZPLA',\n", + " 'AES57JTXM7IOKT74AXQSNL5NNMFQ',\n", + " 'AFTWZJUP2224KGWPBCBBLHS7573A',\n", + " 'AGGLOHDR6L7GZMIFCGXPPHS23OTQ',\n", + " 'AGVLLL3Z55OFM5JTJJWFJFQXPUGQ',\n", + " 'AG5FGEYGAMLVI7NOKMXL7ORUZNDQ',\n", + " 'AHH4EDVBK4H6ZWPSCSNQHX3BRKZA',\n", + " 'AFDMZ4TRX3HXQQUGWAHJQTIF65BQ',\n", + " 'AETE7Y3DZT6BLMWA6U27ADJDZ4LA',\n", + " 'AEINWALDRYT4NTF3M5NC2WZ5YQNA',\n", + " 'AFRVV3L6CJUHLLKWA3PIG7JCYJQQ',\n", + " 'AFPHKIJFGIU4G4POXRFCEF5RJJHA',\n", + " 'AF227ZORVJNXGFF6UFK23IYWE7AA',\n", + " 'AHF2OTODCQC4BETX7CHZMOHUBODQ',\n", + " 'AFDEH7TVRJ4GBWE76Z7RBSHQOC4A',\n", + " 'AGDTHJ7R5N2HOHYK4AACLB53BULA',\n", + " 'AEWFEWBJVI2YN7WAWVXSOYT5MANA',\n", + " 'AHGCCTL7DBBD7FK4RFYAJS53BGOA',\n", + " 'AGOXD3ECHHH2XAFGO6TSSMRZJQVQ',\n", + " 'AHJQPUQLSQZE6LMIUMY7WNRXCQQQ',\n", + " 'AHJQPUQLSQZE6LMIUMY7WNRXCQQQ',\n", + " 'AEYVXZF5TQB7IGLLS3HJTDWLSKJQ',\n", + " 'AGTITI6OKWPN2AVELIAJALJFX6NA',\n", + " 'AEA2AYPIP3RN2YZWRNFKKD6OGGBA',\n", + " 'AHL5ZHN64UHJOGQLPINJ3BN4VBPA',\n", + " 'AEYGPUCRKH7G4VM22FM3VAKSQ23Q',\n", + " 'AEYGPUCRKH7G4VM22FM3VAKSQ23Q',\n", + " 'AEV6OL4GLSYMDNUHS4Y4DNVFDRHQ',\n", + " 'AFFFV4Y35FUSSYUMRHYV4P34X2MA',\n", + " 'AHCZKT34YZL3CVXYVH2CNKQDCYBA',\n", + " 'AF4NIQPIZQ3S3G6KEVQW33DNHZSQ',\n", + " 'AFDPKX3DYZI6FV5GXLI7NVTULR4Q',\n", + " 'AHU2Y2ZFQKI3V3ARFDKZA6ER4NUQ',\n", + " 'AEIHN6JDLYL2QYCAOCBVEUPHU5EA',\n", + " 'AEUMYP5IWSQCLQRIAUKTWR2LZRSA',\n", + " 'AEHJJPC3MQJAHAJWBEVIF5EFQQBQ',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFXF3EGQTQDXMRLDWFU7UBFQZB7Q',\n", + " 'AFDERNB6BIR3U2DOR3S2KX7KJJXQ',\n", + " 'AEIPJBAN7A55Q5DFFPZSR2UV3OKA',\n", + " 'AEIPJBAN7A55Q5DFFPZSR2UV3OKA',\n", + " 'AEIPJBAN7A55Q5DFFPZSR2UV3OKA',\n", + " 'AG3VXRJ5OUQDF3UAEOEIIZ6Z5Z3A',\n", + " 'AG3VXRJ5OUQDF3UAEOEIIZ6Z5Z3A',\n", + " 'AHYARJU3M2CYM3W5SZYL33KOFVHA',\n", + " 'AHPFHP43AXWRYZZ4HPNCW7I7J3ZQ',\n", + " 'AHPFHP43AXWRYZZ4HPNCW7I7J3ZQ',\n", + " 'AEZV3WDCDM6V4CJMN222D52REYYA',\n", + " 'AEG6UV72JH6WOHEAWLMNXT6J7F4A',\n", + " 'AEX3CW22RUBG2EEUYSBZBMTRJSZQ',\n", + " 'AEICZD35OTDYVWA2KPYWN4PDZ2SA',\n", + " 'AEICZD35OTDYVWA2KPYWN4PDZ2SA',\n", + " 'AE6ZACCQOGZIDDWM4TZPAEKUJRHA',\n", + " 'AG4COLOHCLHWUUYWCZ77TPJLE3EQ',\n", + " 'AG4COLOHCLHWUUYWCZ77TPJLE3EQ',\n", + " 'AG4COLOHCLHWUUYWCZ77TPJLE3EQ',\n", + " 'AGBZYPQKIUZGWHXOZZFAMVEQZ5JQ',\n", + " 'AGLQQCIS5V6EGUCS5SSNHWZHQM6Q',\n", + " 'AGLQQCIS5V6EGUCS5SSNHWZHQM6Q',\n", + " 'AGLQQCIS5V6EGUCS5SSNHWZHQM6Q',\n", + " 'AERRX357RLQ6SAUBH6HDYNGTXZ4A',\n", + " 'AFNZHLVWANRWLF3N24KCMPOTYG2A',\n", + " 'AGROPS2VIN3R7UUTWO2F662NSNMQ',\n", + " 'AF4Y2O5Z4P7JZPXUQSR62VAP2I3Q',\n", + " 'AEE2PYYDXJGV6ZO3YHZBBEMSUG4Q',\n", + " 'AEOYNV3GTKOZ2YOEY4QEKIAEZEZA',\n", + " 'AGBOGNMAG3UCA6B4Z6VT62DVNOIA',\n", + " 'AFD6OGB6AY4YPKN62LCTXGYR7KJA',\n", + " 'AFD6OGB6AY4YPKN62LCTXGYR7KJA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AFWVN52MRBWOTIK7UGXBWGOY4HBA',\n", + " 'AGLHRXHXPXK6M7LUU4NZXE3GQFMA',\n", + " 'AGKKCD6TYVYVC2EOWPV6W3DPXOWA',\n", + " 'AET24VX4XLW3GZ2XNFXZNPTE2AVA',\n", + " 'AET24VX4XLW3GZ2XNFXZNPTE2AVA',\n", + " 'AFDDEXBXGKNMWIZQLH3764LUZ7BQ',\n", + " 'AFYMNMPJ7TCETT3PK55JBS57I6DQ',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AFQQQ5LGNSQUEBGDCYBAZZE5T3DA',\n", + " 'AE6T5HPHZOJKN2BGUA3ZAVDKDOWQ',\n", + " 'AEQ5KNRASE5F7HHXZJ7XRN6SBSWQ',\n", + " 'AFRZ3YEUSNVS6THSGMGSWWCMPJ5A',\n", + " 'AEKLWIFD6GVHWJKIC4QDCDYRNYKQ',\n", + " 'AFLX66DKF6R3H6OEOC3TIVAYXZIQ',\n", + " 'AFLX66DKF6R3H6OEOC3TIVAYXZIQ',\n", + " 'AFQ7WYW4KSH4VI5OVXCP2GV6PBRA',\n", + " 'AETGCWXC47MSMK6B2TLZ44KCFJZQ',\n", + " 'AETGCWXC47MSMK6B2TLZ44KCFJZQ',\n", + " 'AF5KHOHRF2PHDZVWJSYAVFUD7C2A',\n", + " 'AEKHCQJBDUCMVSTED7AMOZDC4COQ',\n", + " 'AE5QIQBWPOWOLRSFTK5CXI53EGEA',\n", + " 'AEJWQQYYOFNDGPKXLXJPNBTQLCAA',\n", + " 'AER7BPYAMW5CAICYIJX7QW64MBIA',\n", + " 'AHI7SBHYECQUIS63BKXBHY325VVQ',\n", + " 'AHI7SBHYECQUIS63BKXBHY325VVQ',\n", + " 'AEHWOWAIPMPP2EN6C24JJQROQ5VQ',\n", + " 'AFJP74KDEKRSPJN5JINL452T6WNA',\n", + " 'AHVOLBWSTIHEM6VGNYMEQGVWR2YA',\n", + " 'AF5PN3FPG5Z66P7Z7UWL56D6CGMA',\n", + " 'AFB6GBEYFLU4ARUPS3MESCJPO6JA',\n", + " 'AFB6GBEYFLU4ARUPS3MESCJPO6JA',\n", + " 'AEDKMXFNRORNCFUMIVSRCXZHQXQA',\n", + " 'AHJ2CDYLH4BNPIDVY3TIDSBNRRPA',\n", + " 'AF36B77ISO4OHA5GUTF46F4BJRMQ',\n", + " 'AF36B77ISO4OHA5GUTF46F4BJRMQ',\n", + " 'AHPBIP5JNVD4ZDTULYEAAX2PBDGQ',\n", + " 'AHPBIP5JNVD4ZDTULYEAAX2PBDGQ',\n", + " 'AFITKUE552XUTQQPEO4SIHWHLNMQ',\n", + " 'AFCXJZWRP5BLDWIOBUJ3TZG6OMBA',\n", + " 'AE7ZR5DNB5MPPJ3KNECRHSDEDPUQ',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AFTLUVGQWKW6XSQ5TB6UER5Q263A',\n", + " 'AEUAL3EJKUSTNB4YY6STLYGTJALA',\n", + " 'AGZZ35KI6RBFZYHG4TZPOAIACVMA',\n", + " 'AGZZ35KI6RBFZYHG4TZPOAIACVMA',\n", + " 'AGZZ35KI6RBFZYHG4TZPOAIACVMA',\n", + " 'AGNUU3OZ4L7UGAXA72NJIDDFJYDQ',\n", + " 'AGG63E55UYM5735FTMRLAXL4D5IQ',\n", + " 'AFWVC6NYAO5FZTS25VUIH3H73KZQ',\n", + " 'AFICQHAE6YOEIGE5TYZG5TN7OTRQ',\n", + " 'AFICQHAE6YOEIGE5TYZG5TN7OTRQ',\n", + " 'AF4WLLHTQLRPEZ33OJDYG23MFLKQ',\n", + " 'AF4WLLHTQLRPEZ33OJDYG23MFLKQ',\n", + " 'AF4WLLHTQLRPEZ33OJDYG23MFLKQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AFV22L7AEKI2LW6HMLRLUKNYVBGQ',\n", + " 'AEPQSFDPLHZQ6Y5XB7IUBW4DY5YA',\n", + " 'AGV3JEME5YIGXADUTXWKVZS6Z7JA',\n", + " 'AHTVQZZNC6IVALR2CU2JCAG7FZIA',\n", + " 'AFXFEXKD2XNGFLVJ2MMAXNYJSDAQ',\n", + " 'AGTR4A6CYH6AGEIYCAPYPQZERZLQ',\n", + " 'AGQFGXUGFSZHNRQGP7J24RVSLZSA',\n", + " 'AGQFGXUGFSZHNRQGP7J24RVSLZSA',\n", + " 'AFM5NV37IAPIP2AZXEZTKP3BJWKQ',\n", + " 'AFM5NV37IAPIP2AZXEZTKP3BJWKQ',\n", + " 'AGFKWX5UV6XADCUDKYILHVF2GIQA',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAM2CCKV52HI4YZU7ASZTSXA7YQ',\n", + " 'AGAHANLSS7DG4ZHNPP5S56W4SKHA',\n", + " 'AGAHANLSS7DG4ZHNPP5S56W4SKHA',\n", + " 'AGAHANLSS7DG4ZHNPP5S56W4SKHA',\n", + " 'AEDDULPRRWJ3YVRQJEN56ENGJUDQ',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGMZO7NPGHYPLCOCLMQEDGKNCHVA',\n", + " 'AGGMDRXIZJHBVVQFKU2LJ3LGICTA',\n", + " 'AENWOKSUWWPH7FNTRNP6GPGTHRUA',\n", + " 'AEXTSZOMHUDQZ46764RKBNZ2WANA',\n", + " 'AEXTSZOMHUDQZ46764RKBNZ2WANA',\n", + " 'AG7MO2XSVUHRZKH46X3QXC7LR32A',\n", + " 'AE6EPWEAGVOKWS42HYLLT2CZWTGQ',\n", + " 'AGUNN5632O4AITGTUZQO77YKW5EQ',\n", + " 'AGUNN5632O4AITGTUZQO77YKW5EQ',\n", + " 'AHMO6GV56HC3LYCVNNAPFNWF4HFQ',\n", + " 'AEC4USL3AGDC4UZXCGL6AYRUCBBQ',\n", + " 'AFH37SUSDVJI6GWNF2YSSGAPUB7A',\n", + " 'AFH37SUSDVJI6GWNF2YSSGAPUB7A',\n", + " 'AH65KTF6RTJHRRSAQ62SCEO4YUAA',\n", + " 'AFEUJGH6HN52IP6H7ZD26KYZGEWQ',\n", + " 'AF224BZVIYKHVGJGPKGC3UAVTLQQ',\n", + " 'AGUFDVO4TYIFQHQUMDXFHSHH43BA',\n", + " 'AGGOUUE2QZ23ABB7XE5SCBCGT63Q',\n", + " 'AERUWTJE5HQMM5BOWAHH5E6HFKEA',\n", + " 'AFCSIDWSKICZ5UH26NREKPW25X4A',\n", + " 'AHTOYKLAV35TPN7AAWFB6Q5BIMYA',\n", + " 'AGVQJFWTGNXNOKM6BOGYN7RB3OPA',\n", + " 'AEIY2WXJWZJSCUMR7S4F3AALGPEQ',\n", + " 'AEC75WKIIIK4LDQFKNOKWNFZUYJA',\n", + " 'AGIYSA62BZULHNSJTMPAT5IC3MLQ',\n", + " 'AE54OXZJ3A4QXJLDRE37JABF4WAQ',\n", + " 'AH7P2ZJ7NDT2NNVS7ZEGNEPT2J2Q',\n", + " 'AH7P2ZJ7NDT2NNVS7ZEGNEPT2J2Q',\n", + " 'AHYHK7JKOZ7F7TUDXUWSONLITJJQ',\n", + " 'AHYHK7JKOZ7F7TUDXUWSONLITJJQ',\n", + " 'AFQKWXGOZ6N33TEWPESQEA7NQWIA',\n", + " 'AHIFWJCLH3DZ5S6XBY7XKEKIFNMQ',\n", + " 'AGW47FN4SDTHI2VLAZPPRTTJHVYQ',\n", + " 'AEMZX2FHIAL2R6YPCIXUSWFRB33Q',\n", + " 'AGPSLW4UG4AWFP6AYDV4AFGSHMWQ',\n", + " 'AERBGR3GPGZ4IJMR3C2SYO64PVLQ',\n", + " 'AF6N3BBR32UMXX276IR7CTZTVTQA',\n", + " 'AH2KRJCMDPAGIOGC4MOAQEIHGE2A',\n", + " 'AE4R34JAQMBCEAPRJI5ZAYDVBD4A',\n", + " 'AEI2KJ3JMMUJ4NIVIV64ST4TLMKQ',\n", + " 'AGNNX5XDIN5SHDOKFX2QOUE32B5A',\n", + " 'AFPTOUHUSNEB6JDSCWDMLS23L4CA',\n", + " 'AG4DEQCBVNCJPRHXC3S255BBJALQ',\n", + " 'AG4DEQCBVNCJPRHXC3S255BBJALQ',\n", + " 'AHKLYY7DZ4RECGZXP6KUALGUFRJA',\n", + " 'AE5GHFQZ6IXM4QNYTLTYJO24KQZQ',\n", + " 'AHCG7XEDVLOCFOQMZC26VE33NW2Q',\n", + " 'AFMHO73ZLBHUMB36EHB4GUFLM3SA',\n", + " 'AETOPBLLOVEAMSUYLIVTIKRWTGZA',\n", + " 'AH6U3RG4SKWXF4KNH3RC6VD5P4QQ',\n", + " 'AH6U3RG4SKWXF4KNH3RC6VD5P4QQ',\n", + " 'AGCUONI7ZAZ4SCQWIUQCV7LRU7VQ',\n", + " 'AEEZXJJJZMYYUHBQJ3E6Y5GYLD5Q',\n", + " 'AHVOQ4CBGSXUQKOR2A3BPCV53YMA',\n", + " 'AHVOQ4CBGSXUQKOR2A3BPCV53YMA',\n", + " 'AHVOQ4CBGSXUQKOR2A3BPCV53YMA',\n", + " 'AGYU3KLQWZIUYKAXV7YARVZGUI2Q',\n", + " 'AG6K7GPCDHQNKMVDMTYKKWSOAVVQ',\n", + " 'AG6K7GPCDHQNKMVDMTYKKWSOAVVQ',\n", + " 'AG6K7GPCDHQNKMVDMTYKKWSOAVVQ',\n", + " 'AFHRPCWEWPAAA2ZVLDTJHDIFR3VA',\n", + " 'AFHRPCWEWPAAA2ZVLDTJHDIFR3VA',\n", + " 'AFHRPCWEWPAAA2ZVLDTJHDIFR3VA',\n", + " 'AF3Q2MGLBSXB3QSTZJCTDM4V4CMQ',\n", + " 'AF3Q2MGLBSXB3QSTZJCTDM4V4CMQ',\n", + " 'AF3Q2MGLBSXB3QSTZJCTDM4V4CMQ',\n", + " 'AGRXRS7Y7ALTQP4VVJEWEDWUKVFA',\n", + " 'AHL5UAIYCGYOTCHEY6HJKOMJTF6A',\n", + " 'AFKJQMCY3HIYNHN3FEMLQXPGIPWA',\n", + " 'AGNQVHZDKTKGX6OYVTEWV53YIQSQ',\n", + " 'AFH7ZT2NJSHDKJ43IODXCE6RHWVA',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AFGDRVPCP742YM5MMLFIKZCGNNRQ',\n", + " 'AH74JVFA53ZGMIJCHYOE22SLB3FA',\n", + " 'AHSWBB6FZBEA7W7PMSO4L5SC7ERQ',\n", + " 'AG3RUN6QXDMTDGTA7MXGFMDUILBQ',\n", + " 'AH5KJVUUL3UMJMTCSHPHGBQAZHOQ',\n", + " 'AFOMMZPFMNVCAC6VYYGQPJSRZFTQ',\n", + " 'AFT7NN6XCSB73I3TSVAZRWNKNJZQ',\n", + " 'AF3SSXF4RK6JEPW7WGJQPM32DUGQ',\n", + " 'AFO5WBJKP6QSOESYMPNWUXXYUEJA',\n", + " 'AFYD3C45KSVRKLLKA5S76U33FM2Q',\n", + " 'AHWW3GBNSOSLWDZBZ26ELXLGQJXA',\n", + " 'AGNKRWFIR7RCHG4YPSDL7P3GMGBA',\n", + " 'AEZHRMVXXEGT4LCKGDCWWCA6ME7Q',\n", + " 'AGJ7WPIMFSZFTQZHI622C56V4DWA',\n", + " 'AGJ7WPIMFSZFTQZHI622C56V4DWA',\n", + " 'AEQJQXW6PQAU5WEJGXS42BZ6GCVQ',\n", + " 'AGNT4XZCCKWQQBTRXLGEQXEU2OOQ',\n", + " 'AFERCDY2EFJKT7QUQ75GISNHTFOQ',\n", + " 'AF5YGFIDUL4PVHGLOLLCE2ZOZSCA',\n", + " 'AHKHMWNLW3LCZCJXWLZVKC744UDQ',\n", + " 'AHKHMWNLW3LCZCJXWLZVKC744UDQ',\n", + " 'AE5K7JZDVDIEJM53R5HRNZZGJ2IQ',\n", + " 'AF6LYZ3MUF4YJFGN7VGQWMWLSUFQ',\n", + " 'AGU3DPKNTSMZP4QVNBGMZNQSVKFQ',\n", + " 'AE2ODKIC3GWQTSYKDMMIYHPJZ7IA',\n", + " 'AFAD64BC3SGKIFKIVBS4HOVWTDXQ',\n", + " 'AGODEE2NRFP5H2KRXIZPZPV5QSJQ',\n", + " 'AEXUHHBGMR5MZWUYXFLZ6XKVLCTQ',\n", + " 'AEXUHHBGMR5MZWUYXFLZ6XKVLCTQ',\n", + " 'AEYE3LSUHQEX6BWG224MKVXX6XZQ',\n", + " 'AGLYZN4FZXZUWA2UPAJDWIDHUXFA',\n", + " 'AEZBFZHVLG7CMLFKRNEDYYYMEYZQ',\n", + " 'AEI6PVESNCWAQYNYNQ25O4U4OIHQ',\n", + " 'AEI6PVESNCWAQYNYNQ25O4U4OIHQ',\n", + " 'AFOSMON6MEJJHCNC2QAHGQQOFKUA',\n", + " 'AFOSMON6MEJJHCNC2QAHGQQOFKUA',\n", + " 'AHNZGXDDP6KMIZ3JWII47NK72OLA',\n", + " 'AGSV4K43Q6TIIHGN6BB2Q5A2I5PA',\n", + " 'AEJDFPQZNZYNSBFL5DNAHYZFFRBQ',\n", + " 'AH6LSFADKK56ZXNWKN32R2HPR2FA',\n", + " 'AH6LSFADKK56ZXNWKN32R2HPR2FA',\n", + " 'AGM7RCFVS3FJ7WGW2BUIQHN34NZA',\n", + " 'AFISRL535I2D5IUPG3FGWY6XZC7A',\n", + " 'AGKSSNLDIG5HY5FXYVE6UVXKVDYQ',\n", + " 'AHPXDXGUHYKWYX6KIKCH2IB4DFUQ',\n", + " 'AH57UQ3IE2TH2COG2LKAIHVE6OKQ',\n", + " 'AH57UQ3IE2TH2COG2LKAIHVE6OKQ',\n", + " 'AGJFPQJ5UH5BQEQGL6GKURTN6XZA',\n", + " 'AFWQKUQAAN4XCFE6Y66VI5AOO4ZA',\n", + " 'AEYB24ATMPTFOMYIHSYYRN4MZUOA',\n", + " 'AEWUOTR5BLPGWHAJI24EMWJHXORA',\n", + " 'AG6K2WLPXCRUL24DHHFXACBYLOBA',\n", + " 'AFSH2ADUKP7QBX2P6BCWUKZYE5NQ',\n", + " 'AG7J2YXTPA2J6USGMRCDRXP27AUA',\n", + " 'AEBIQICUNDRDP6YCUGOCC7GTIEPQ',\n", + " 'AHQKDADRWYPGGJFCUD3WI4ANDQXQ',\n", + " 'AHAWL3U7UKXOVLS5EGO7ZWROEHZA',\n", + " 'AH2SK57JTJATVPUL34OIS44AQARA',\n", + " 'AH2SK57JTJATVPUL34OIS44AQARA',\n", + " 'AFMKRGS25NE4HPMVPBDC6M2BKUYA',\n", + " 'AGHU6Z5VO7EX3QY5OEAUMPOU7AAQ',\n", + " 'AGN65FCMRQSRXS6PWIVSUYIDZXFA',\n", + " 'AHEVUFDDDQV4763ZYIA745KOXUUA',\n", + " 'AGQANGDZQGK2IOWOXHOCTPBPQRKA',\n", + " 'AHTOAHVOFQFZ7I5HPDVJSEASCRZQ',\n", + " 'AHTOAHVOFQFZ7I5HPDVJSEASCRZQ',\n", + " 'AEK5ZLRN23DCNUWP3GHTONPO4DWA',\n", + " 'AF5BYRAWORXLQNHT3IAPKOQOGTRA',\n", + " 'AGNFCXSJSYDHFRF4ZKIEDV3GVZFA',\n", + " 'AFUSWNVA72MMWHGYWJ652SYX2JJQ',\n", + " 'AFUSWNVA72MMWHGYWJ652SYX2JJQ',\n", + " 'AFUSWNVA72MMWHGYWJ652SYX2JJQ',\n", + " 'AFUSWNVA72MMWHGYWJ652SYX2JJQ',\n", + " 'AFJJBA225IQUMV35ZORXSVFZDMVA',\n", + " 'AF5HMGO6S5NUN4QR3DJBP6ZVIEIA',\n", + " 'AFWRGOGF4AI2IHRX7KZ2IYL63RXA',\n", + " 'AFWRGOGF4AI2IHRX7KZ2IYL63RXA',\n", + " 'AFWRGOGF4AI2IHRX7KZ2IYL63RXA',\n", + " 'AFWRGOGF4AI2IHRX7KZ2IYL63RXA',\n", + " 'AHGAWWBYLYK3OM3D7RBFM2DZKIHQ',\n", + " 'AGATJUDC7FC3FLKDSDC5DM3RRVCA',\n", + " 'AEDTXOC3YW6O7P2UPM22VNNRF77A',\n", + " 'AEVRP23ONGIWRUAPURGPAKC4PL2Q',\n", + " 'AEYK5YGOKGJJ6QYYWDV32ST23Q7A',\n", + " 'AHBNWEJNOKN4BD2QMP3LUZUG6MAQ',\n", + " 'AF62EAAIQCFJ6FDZ2L4W5LEAKUIA',\n", + " 'AF62EAAIQCFJ6FDZ2L4W5LEAKUIA',\n", + " 'AGW7DNVEEOZ55KAPREK54O7DYLKA',\n", + " 'AHINTWLUQQLLDM437NMPMEDDUD4Q',\n", + " 'AHINTWLUQQLLDM437NMPMEDDUD4Q',\n", + " 'AGQCFT47KDI77JKRSOMAK34MJPAQ',\n", + " 'AFPV346BBPR4OSAIFCN5I7T7TP5A',\n", + " 'AGS47C3SO62X375JL7RWNBKCFXXA',\n", + " 'AGS47C3SO62X375JL7RWNBKCFXXA',\n", + " 'AGS47C3SO62X375JL7RWNBKCFXXA',\n", + " 'AGS47C3SO62X375JL7RWNBKCFXXA',\n", + " 'AHPKUK33JPVJZQJOPUSPIBCAYBBA',\n", + " 'AHU2GG5RF6YAEWUFNLH3QH5RHDNQ',\n", + " 'AHU2GG5RF6YAEWUFNLH3QH5RHDNQ',\n", + " 'AE2WMFLNQAV4U5O5XL7AU7LYSL3Q',\n", + " 'AE2WMFLNQAV4U5O5XL7AU7LYSL3Q',\n", + " 'AEX5IK5WUXIGLSWUWSNDYATYVQJA',\n", + " 'AGDR3CBX2GWY3JKGDLMUERVFWPTQ',\n", + " 'AHTMAPDOHUZ225CTU4K2E3BFBPBQ',\n", + " 'AFGNAQM465VDQYDIWW7WBZEUMN2Q',\n", + " 'AEBDKPMDIM267M2A2JNR37RTNIRQ',\n", + " 'AEXCBVLSGIQSEK3UIPLMFEVN6LSQ',\n", + " 'AEVBOKQVPBUGU74U6FWZON46R6ZQ',\n", + " 'AEDW2OT6QODQHYU6Q6VUBLUFOOIQ',\n", + " 'AF4WXU322AWYRJ5S7HE6CEBQMEFQ',\n", + " 'AF2UCXKR6DC75YORQSCINN2E7B6A',\n", + " 'AEIN65QSZZQ7LR3MSPIYAIES6GNQ',\n", + " 'AFJVYJ75233DFO3FZYXTELUZLUGA',\n", + " 'AGPJXWOVUYDJHAGKCHQ4AK2AVGZQ',\n", + " 'AF6FP5XNZKQFS7NB5WG5AAUZXATA',\n", + " 'AF6FP5XNZKQFS7NB5WG5AAUZXATA',\n", + " 'AF6FP5XNZKQFS7NB5WG5AAUZXATA',\n", + " 'AFHZAI5WNVWT4SFFY2EZ2SGSCIAQ',\n", + " 'AED5CY57L474C37AHNRMT3BTS5LA',\n", + " 'AFFO2TXPGQVHVTIMFRGT5YZ7M4OA',\n", + " 'AG3JVDYPQD5TEE7WCI5OK46MSMRA',\n", + " 'AGTMZCWIWBH43TCW7UKG2YV2EKKA',\n", + " 'AHYEPW2M6FS4LOSZH3JYO47ET2WA',\n", + " 'AGAUXWCVEMG4NHHLM5QYOWMWWRVQ',\n", + " 'AGAUXWCVEMG4NHHLM5QYOWMWWRVQ',\n", + " 'AELN54HSLHAIITISZ7WNFUGPFQTA',\n", + " 'AHJLE24BKWMCMJ72W7XYMLCXKIGA',\n", + " 'AET7USDGJ7EL5YUJU55S32IFRZDQ',\n", + " 'AGVOCAFRQ6W2PWADY27GTWIHVVJA',\n", + " 'AEALMYGML4SPUXDCK3RDDSXBIGUA',\n", + " 'AG7U3U2RPLN3LW5P4CUVUHINRMOA',\n", + " 'AG7U3U2RPLN3LW5P4CUVUHINRMOA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AHPOHKN4PU4W3V5PGFL7AGTAD2AA',\n", + " 'AFIV4SN6MTZTNSKICMACWGG5REFQ',\n", + " 'AE5NJ373RYNSSYEROFQ6YMKJ6XWA',\n", + " 'AFTEMMCIMU62ONZHLLXEXSME4Z6Q',\n", + " 'AFTEMMCIMU62ONZHLLXEXSME4Z6Q',\n", + " 'AFTEMMCIMU62ONZHLLXEXSME4Z6Q',\n", + " 'AFTEMMCIMU62ONZHLLXEXSME4Z6Q',\n", + " 'AFTEMMCIMU62ONZHLLXEXSME4Z6Q',\n", + " 'AHF4MTJVRIWG2GK3JLSBKYQYHGDQ',\n", + " 'AHAEAFCDBBBD7QSNL3OIEFE2F2AQ',\n", + " 'AGDOCJ45DHF6JVD23PLTNOH5BHHQ',\n", + " 'AHRGTIMQO47C2VLJILIDU53BQKSA',\n", + " 'AHRGTIMQO47C2VLJILIDU53BQKSA',\n", + " 'AFUHQI57RBU4SVZEM55LB2FHAPWQ',\n", + " 'AFUHQI57RBU4SVZEM55LB2FHAPWQ',\n", + " 'AG64D7OAG3IYLHPMFIDIALPO4QZQ',\n", + " 'AFXM3YJ4TA4ESZJWGYY65PDL5YNQ',\n", + " 'AE5UYN4TT4EE55XLVLKQCO6IHEYQ',\n", + " 'AGYXMSSKCFQQ25LG4K5WDFOZSDRA',\n", + " 'AGYXMSSKCFQQ25LG4K5WDFOZSDRA',\n", + " 'AGK47D52WHEZWIW3RGMLDNDGZ32A',\n", + " 'AGFYPDLGSZU6QY6KIW6JZW6CK2CQ',\n", + " 'AEJFGVOJDY43M34SKOQ73MR5LDOQ',\n", + " 'AFEZH43XDG42KHOX4ZDOISHOJJMQ',\n", + " 'AGTAGFJK3FZRO643NK5GYNPOXTUQ',\n", + " 'AHCNFZOIVLKA3FV54MREJJMSDHFA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AFFCQNWCHXTY7BANIWXLP5C2BKPA',\n", + " 'AECCHBPAQIKZS2ALD6MVJOO3CWKQ',\n", + " 'AFAFNPANVWPP3VFRJHQZOU7R6X2Q',\n", + " 'AEOVCZC77QZJQPBIAIKCFV7AS7PA',\n", + " 'AHJRS3AHOMWOGYEWUAFF6MDEJY4A',\n", + " 'AHFQM2AORFUYHAE2O4IIHFU5QCGA',\n", + " 'AGO73GPAF65RB7XZGZL5L3QVY2JA',\n", + " 'AHBVTZVQSHLVHMK5N3NOHKNCNJPA',\n", + " 'AH4UNA3HYDPXDLP7OETQQOQQDWYA',\n", + " 'AFS5TQHRDNYDFD7ONWOVFWTCGAKQ',\n", + " 'AH6PHAHWPMJDA4UXVJS6ZGZWE3SQ',\n", + " 'AH2HBIU5M2KOE4WHRXEZV2CUTHZA',\n", + " 'AH2HBIU5M2KOE4WHRXEZV2CUTHZA',\n", + " 'AHY3NVIU6WQZIP522P7ZGQPE7QWQ',\n", + " 'AEJ33R64CS46LK4ZN3RHTLTBO4ZQ',\n", + " 'AG4U7OO7EGQXH5KTGPWNFM3AC5MA',\n", + " 'AFQ4A4DZ6PYJYZJXKXCNEONVD24A',\n", + " 'AGAPXZJESA3RADJKPXMASS2TT5QA',\n", + " 'AE5LTGA5XU7NVIGVQKDQ6N2Z7GRQ',\n", + " 'AHBUO2AFI46Y3SDHRMETHIGRUONQ',\n", + " 'AFRKVKLMCTJGCLALZIHEJSZ326SA',\n", + " 'AFJNVGGMMQAIDULOVPTR2MPBEIMQ',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AF2BLE54TEMGZ546U763ZHZRXC4A',\n", + " 'AE5E4D2GGRABRQOO6XKKK7ZEKPIQ',\n", + " 'AFAAITODQWTP5HUV2E7QDRXRHERA',\n", + " 'AFAAITODQWTP5HUV2E7QDRXRHERA',\n", + " 'AFAAITODQWTP5HUV2E7QDRXRHERA',\n", + " 'AFSGI24VGE7QZS7QUKIEJGGEF4QQ',\n", + " 'AGXRSHOXP2NVH5JT563MX574I72Q',\n", + " 'AEONXM4J7LCG3G4JNSNSCBZ4MDNA',\n", + " 'AHAHXJJYDAJSSAXO3OLJ3HGRCBPQ',\n", + " 'AEEDFUQ7SXVEZ4VBHTED5D6MZ7QA',\n", + " 'AEEDFUQ7SXVEZ4VBHTED5D6MZ7QA',\n", + " 'AEEDFUQ7SXVEZ4VBHTED5D6MZ7QA',\n", + " 'AEHO2WBZQTHF2UYNRQOHP6PASYHQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AFHPJTBQYQHQXIFBAODXDAIGCGMQ',\n", + " 'AHR6RGZTLOMBD7EBF3OK43JWMGNQ',\n", + " 'AGZMKHWSCB3UXDGFUPFRZSL4EAWQ',\n", + " 'AGZMKHWSCB3UXDGFUPFRZSL4EAWQ',\n", + " 'AGZMKHWSCB3UXDGFUPFRZSL4EAWQ',\n", + " 'AGZMKHWSCB3UXDGFUPFRZSL4EAWQ',\n", + " 'AGZMKHWSCB3UXDGFUPFRZSL4EAWQ',\n", + " 'AFIS3XBH5KRSGHGJUFRTYBTFGEEQ',\n", + " 'AETEK5ENT3ZFKBCPJ4ETALYQXY2Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AF453YWNMOPDI5XRRVQOIF56NM4Q',\n", + " 'AGTV3IO25IJNDMEPGK2IBM6WZ7MQ',\n", + " 'AGTV3IO25IJNDMEPGK2IBM6WZ7MQ',\n", + " 'AE7YYSYFEWAYIUCAK4W33CHPP4JQ',\n", + " 'AE7YYSYFEWAYIUCAK4W33CHPP4JQ',\n", + " 'AE7YYSYFEWAYIUCAK4W33CHPP4JQ',\n", + " 'AE7YYSYFEWAYIUCAK4W33CHPP4JQ',\n", + " 'AE7YYSYFEWAYIUCAK4W33CHPP4JQ',\n", + " 'AFNUEZFQIFN6SFAWG6WLHR3IVLLQ',\n", + " 'AFJ74T4L5ZMC7PCNN4C567JNFWWA',\n", + " 'AHUV6QJJIJPSYDUGY3RFYZOHPIFA',\n", + " 'AF6CN6PFI7EGYFVCXE5TKJNN5ZEA',\n", + " 'AEOXJH67IK6A7MAATXDVRAMR4TPA',\n", + " 'AEWOCOJGLNR3RFQSR73J2KGY3ENQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AGVXN42IKSKKBNVFGKCMKIZEBNSQ',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AE3X7PNUWXQU6FZQLQGIA6ZT45QA',\n", + " 'AHU45NZTYUKII5KWB47OI5NH3QLQ',\n", + " 'AFJ4YAHXPKZQSEJTCCJ5Z4KPYZKA',\n", + " 'AFJ4YAHXPKZQSEJTCCJ5Z4KPYZKA',\n", + " 'AFJ4YAHXPKZQSEJTCCJ5Z4KPYZKA',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AGZZXSMMS4WRHHJRBUJZI4FZDHKQ',\n", + " 'AHUKDCTHM6YIDIY7CDZMXBF2NU5Q',\n", + " 'AFXAMSEN6MT4WQHSXCV4JRGXWODA',\n", + " 'AFXAMSEN6MT4WQHSXCV4JRGXWODA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AGDFLGBDHOLOASHN4K6ICKMAWEOA',\n", + " 'AEXEZ3PIBH37ILP6K6ZIGAZZJ7CA',\n", + " 'AHZQKBA7BNCQH4CHTAKL4KX7BULA',\n", + " 'AHZQKBA7BNCQH4CHTAKL4KX7BULA',\n", + " 'AFXMJCVLRCGRAEC7P37FZHEB24UQ',\n", + " 'AFXMJCVLRCGRAEC7P37FZHEB24UQ',\n", + " 'AFXMJCVLRCGRAEC7P37FZHEB24UQ',\n", + " 'AHGZX4XSJUP5YNAEKCZOXX3FRKNQ',\n", + " 'AEP4CUO23WOOOEYSJBXWYLLHD5IQ',\n", + " 'AEP4CUO23WOOOEYSJBXWYLLHD5IQ',\n", + " 'AEP4CUO23WOOOEYSJBXWYLLHD5IQ',\n", + " 'AEI342MDA32TKMKQ7PEPNHCQ3MWQ',\n", + " 'AFI44N5JJZHC3P7SOQWMWXHNWNZQ',\n", + " 'AF6OCVGAI4ODVHGZ4FIPAU5IYCWA',\n", + " 'AFRU45DESG72MNB6FNVBEOOYGHBA',\n", + " 'AFMDE2DGQYBYM4XPLOW74YUUCJWQ',\n", + " 'AFMDE2DGQYBYM4XPLOW74YUUCJWQ',\n", + " 'AFMDE2DGQYBYM4XPLOW74YUUCJWQ',\n", + " 'AHVCBFA26MVQML3Q3777WCGATSIQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AGD25H7BIT2JUXSIOPYCYB23J3ZQ',\n", + " 'AFJQB3AGZHG4UJT452DN4NFODKPQ',\n", + " 'AENE4O4RTVRK6N2VUTSUGTPKS46A',\n", + " 'AGF6JAXKV7UV6MREBJ5FGHLAQ65Q',\n", + " 'AHZZJQYNVZUJNPNQ737ITGEQUB4A',\n", + " 'AGDSEYGSA5K664EUHWKV3ARDXO2Q',\n", + " 'AGXHD5W7H56U5PYVKV677VFNYQRA',\n", + " 'AHPTMNP3Y4FGG7TX2SO6DQCVNHPQ',\n", + " 'AEKB7DPBZAAB4GZFCWO24MFAVUZA',\n", + " 'AFULZJNHK6KFYTA5PJPBNSRIR4HA',\n", + " 'AFULZJNHK6KFYTA5PJPBNSRIR4HA',\n", + " 'AFULZJNHK6KFYTA5PJPBNSRIR4HA',\n", + " 'AFJOSWMUZ5OITR3FQ5H2HUUCK5TQ',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AEXGISIVX7WBUNI7UHHERVB3DF7Q',\n", + " 'AFBXVB2GIANS2DHWDK3HXISL2WEA',\n", + " 'AFBXVB2GIANS2DHWDK3HXISL2WEA',\n", + " 'AFBXVB2GIANS2DHWDK3HXISL2WEA',\n", + " 'AE462K7ARMFX3P7CX2QRL62RR7EA'],\n", + " 'timestamp': [1588687728923,\n", + " 1588615855070,\n", + " 1589665266052,\n", + " 1643393630220,\n", + " 1609322563534,\n", + " 1598567408138,\n", + " 1631885519443,\n", + " 1634275259292,\n", + " 1627391044559,\n", + " 1626614511145,\n", + " 1626211245370,\n", + " 1621184430697,\n", + " 1619737501209,\n", + " 1617904219785,\n", + " 1613319236253,\n", + " 1607339460872,\n", + " 1598212476613,\n", + " 1596473351088,\n", + " 1593352422858,\n", + " 1547589843451,\n", + " 1547589356557,\n", + " 1508770624887,\n", + " 1404402463000,\n", + " 1475756226000,\n", + " 1578611984772,\n", + " 1584799493853,\n", + " 1522091824726,\n", + " 1500768914981,\n", + " 1603130609586,\n", + " 1589724040497,\n", + " 1621356942148,\n", + " 1568236063550,\n", + " 1675826333052,\n", + " 1596901440832,\n", + " 1592452852671,\n", + " 1406073199000,\n", + " 1608936024878,\n", + " 1489880060000,\n", + " 1577694848810,\n", + " 1649634131604,\n", + " 1607532414595,\n", + " 1606300801565,\n", + " 1623459734108,\n", + " 1585005652909,\n", + " 1603586386842,\n", + " 1609434807770,\n", + " 1648824907536,\n", + " 1582901059423,\n", + " 1582900994981,\n", + " 1559999072586,\n", + " 1485955955000,\n", + " 1478783674000,\n", + " 1561738244885,\n", + " 1640896526461,\n", + " 1568217083791,\n", + " 1656871648888,\n", + " 1629166303947,\n", + " 1598833004245,\n", + " 1585211251700,\n", + " 1640916617087,\n", + " 1598751954697,\n", + " 1595533702899,\n", + " 1558659241786,\n", + " 1538856068174,\n", + " 1618455607966,\n", + " 1594448236479,\n", + " 1539756902433,\n", + " 1626092275982,\n", + " 1663163956007,\n", + " 1660417831321,\n", + " 1660417672640,\n", + " 1644349248608,\n", + " 1629410931015,\n", + " 1628462041411,\n", + " 1623250199261,\n", + " 1623188037011,\n", + " 1614292985923,\n", + " 1610133666100,\n", + " 1607744901734,\n", + " 1605885919061,\n", + " 1605814409168,\n", + " 1605292060685,\n", + " 1597942744359,\n", + " 1597526701753,\n", + " 1593190594550,\n", + " 1593043740906,\n", + " 1591977214185,\n", + " 1588865592842,\n", + " 1585261263214,\n", + " 1583932042329,\n", + " 1582999036646,\n", + " 1581772960365,\n", + " 1580742144072,\n", + " 1579351461183,\n", + " 1579312780004,\n", + " 1578928089878,\n", + " 1577024355925,\n", + " 1562550265320,\n", + " 1550588697518,\n", + " 1548092773968,\n", + " 1547157494554,\n", + " 1545303800417,\n", + " 1544236907167,\n", + " 1541942181487,\n", + " 1476542748000,\n", + " 1475838820000,\n", + " 1467123218000,\n", + " 1460413688000,\n", + " 1455464933000,\n", + " 1454626110000,\n", + " 1442016268000,\n", + " 1429911787000,\n", + " 1424200292000,\n", + " 1416250542000,\n", + " 1634176814922,\n", + " 1402260693000,\n", + " 1650493937328,\n", + " 1623525912344,\n", + " 1594585640346,\n", + " 1424462892000,\n", + " 1638429977437,\n", + " 1485824872000,\n", + " 1438740353000,\n", + " 1443695835000,\n", + " 1564768107233,\n", + " 1608394879270,\n", + " 1396202725000,\n", + " 1335035659000,\n", + " 1623731243389,\n", + " 1618369706958,\n", + " 1662827578220,\n", + " 1494861969000,\n", + " 1668797223375,\n", + " 1621631476435,\n", + " 1618934798418,\n", + " 1617909095488,\n", + " 1616954539796,\n", + " 1616457223039,\n", + " 1615701950469,\n", + " 1611448884100,\n", + " 1609182507469,\n", + " 1608753663995,\n", + " 1606878884208,\n", + " 1606103453308,\n", + " 1604762653089,\n", + " 1598591443230,\n", + " 1594848248797,\n", + " 1593321721590,\n", + " 1585080133476,\n", + " 1556652791507,\n", + " 1551117781592,\n", + " 1544671934783,\n", + " 1544671363612,\n", + " 1544671031249,\n", + " 1544238606316,\n", + " 1578102944639,\n", + " 1560125848309,\n", + " 1590518308997,\n", + " 1577565491019,\n", + " 1568419120457,\n", + " 1597662552680,\n", + " 1596392785763,\n", + " 1589245725737,\n", + " 1618610548008,\n", + " 1506959529406,\n", + " 1511227942962,\n", + " 1479946947000,\n", + " 1660169254485,\n", + " 1512070575387,\n", + " 1523468483136,\n", + " 1555966372881,\n", + " 1478620613000,\n", + " 1590717312577,\n", + " 1660780044308,\n", + " 1603469830139,\n", + " 1635164612192,\n", + " 1544161752047,\n", + " 1632773060620,\n", + " 1416800039000,\n", + " 1625603129050,\n", + " 1559566443959,\n", + " 1577295338919,\n", + " 1532273347746,\n", + " 1583124576508,\n", + " 1541698828578,\n", + " 1547272724448,\n", + " 1436290014000,\n", + " 1607976609742,\n", + " 1429626975000,\n", + " 1529939772384,\n", + " 1595705751746,\n", + " 1597361848873,\n", + " 1666268588427,\n", + " 1654314287951,\n", + " 1653607216628,\n", + " 1653519351455,\n", + " 1650921998863,\n", + " 1647381362768,\n", + " 1647216897957,\n", + " 1647121848816,\n", + " 1638840554514,\n", + " 1634341134612,\n", + " 1634340599912,\n", + " 1633643242306,\n", + " 1631367075148,\n", + " 1627688833474,\n", + " 1626992201828,\n", + " 1626976613839,\n", + " 1626477225322,\n", + " 1625692049016,\n", + " 1625006698955,\n", + " 1624659702420,\n", + " 1624399417259,\n", + " 1624274497670,\n", + " 1623796829059,\n", + " 1623707102432,\n", + " 1623704536971,\n", + " 1623116811042,\n", + " 1622753896821,\n", + " 1622752434756,\n", + " 1622389389771,\n", + " 1622303084098,\n", + " 1621205988847,\n", + " 1621202702614,\n", + " 1621138223667,\n", + " 1621043900381,\n", + " 1620424267961,\n", + " 1620252626061,\n", + " 1619563023776,\n", + " 1618184630323,\n", + " 1617844602299,\n", + " 1617487527934,\n", + " 1617407475594,\n", + " 1616718655307,\n", + " 1614896960702,\n", + " 1614796759758,\n", + " 1614292707452,\n", + " 1614036953464,\n", + " 1613949623459,\n", + " 1612821735228,\n", + " 1611965730476,\n", + " 1611360452090,\n", + " 1611183336145,\n", + " 1611102853719,\n", + " 1611101505456,\n", + " 1610417575774,\n", + " 1610322554727,\n", + " 1610062915805,\n", + " 1609849628351,\n", + " 1609804845102,\n", + " 1608329596770,\n", + " 1608329372192,\n", + " 1607986785933,\n", + " 1606592309440,\n", + " 1606592038866,\n", + " 1606524744605,\n", + " 1606518368441,\n", + " 1601776779300,\n", + " 1599882609367,\n", + " 1598818621900,\n", + " 1598665451686,\n", + " 1584497096251,\n", + " 1582858335913,\n", + " 1581997877865,\n", + " 1581257263753,\n", + " 1580949934338,\n", + " 1556243557316,\n", + " 1548208863985,\n", + " 1545955740686,\n", + " 1545265199508,\n", + " 1533246198393,\n", + " 1525225458858,\n", + " 1457053429000,\n", + " 1615437211644,\n", + " 1621793733924,\n", + " 1613990926603,\n", + " 1601610002355,\n", + " 1645538336229,\n", + " 1511803283739,\n", + " 1548416124642,\n", + " 1554218993335,\n", + " 1502540856260,\n", + " 1431384823000,\n", + " 1642619655502,\n", + " 1549824280491,\n", + " 1537891397672,\n", + " 1490896098000,\n", + " 1574985122746,\n", + " 1579932116626,\n", + " 1575522979689,\n", + " 1557634221209,\n", + " 1612909775989,\n", + " 1586811608882,\n", + " 1506959249870,\n", + " 1400122886000,\n", + " 1575653138464,\n", + " 1460045074000,\n", + " 1638640586813,\n", + " 1567368212097,\n", + " 1500512726734,\n", + " 1451837514000,\n", + " 1385235841000,\n", + " 1561398448255,\n", + " 1441042840000,\n", + " 1625801142291,\n", + " 1604465157671,\n", + " 1604270002849,\n", + " 1596077526431,\n", + " 1595905888763,\n", + " 1594595776808,\n", + " 1593851504430,\n", + " 1593668164675,\n", + " 1592174821054,\n", + " 1591751272438,\n", + " 1555689209017,\n", + " 1544138590400,\n", + " 1342568231000,\n", + " 1633197134865,\n", + " 1521501642150,\n", + " 1593203334488,\n", + " 1548703498279,\n", + " 1659396974076,\n", + " 1638394887039,\n", + " 1616016113603,\n", + " 1615562997949,\n", + " 1613597095455,\n", + " 1604423044373,\n", + " 1603476184645,\n", + " 1603305176680,\n", + " 1603219657160,\n", + " 1600120669811,\n", + " 1600009097137,\n", + " 1599670255886,\n", + " 1597681569330,\n", + " 1596927321037,\n", + " 1595783032290,\n", + " 1595609922802,\n", + " 1594062266873,\n", + " 1594061511452,\n", + " 1593625097634,\n", + " 1593187544786,\n", + " 1591809773059,\n", + " 1584657434170,\n", + " 1583863571467,\n", + " 1583174848067,\n", + " 1583172004166,\n", + " 1582569041506,\n", + " 1582230857731,\n", + " 1581974143974,\n", + " 1581009311452,\n", + " 1580765754206,\n", + " 1580583215715,\n", + " 1578165361970,\n", + " 1577225566969,\n", + " 1577144708939,\n", + " 1576886354161,\n", + " 1576792023399,\n", + " 1576781162840,\n", + " 1543796311548,\n", + " 1488571685000,\n", + " 1549059146613,\n", + " 1559439111074,\n", + " 1517790815912,\n", + " 1560351059878,\n", + " 1590494584901,\n", + " 1540152932498,\n", + " 1612843218308,\n", + " 1619087472258,\n", + " 1519089494463,\n", + " 1613158713991,\n", + " 1616267930583,\n", + " 1620061973147,\n", + " 1520193927991,\n", + " 1521509754787,\n", + " 1653790207854,\n", + " 1653790152450,\n", + " 1558344666992,\n", + " 1605655809782,\n", + " 1533062465403,\n", + " 1674411398983,\n", + " 1581890088990,\n", + " 1568935503459,\n", + " 1613669058600,\n", + " 1546154772002,\n", + " 1523292912731,\n", + " 1496889336000,\n", + " 1667883666641,\n", + " 1645670901482,\n", + " 1619717251496,\n", + " 1605958100914,\n", + " 1605504915917,\n", + " 1641155480823,\n", + " 1637813050565,\n", + " 1636609755321,\n", + " 1634788179197,\n", + " 1634703622638,\n", + " 1634620228424,\n", + " 1633493361989,\n", + " 1633300299293,\n", + " 1633216734665,\n", + " 1632284565449,\n", + " 1631484677201,\n", + " 1631396333149,\n", + " 1630730370399,\n", + " 1629763023330,\n", + " 1629669965200,\n", + " 1629054964948,\n", + " 1627012363828,\n", + " 1626758945482,\n", + " 1623708059221,\n", + " 1623701272153,\n", + " 1623105219553,\n", + " 1621788041474,\n", + " 1621623173577,\n", + " 1669695114467,\n", + " 1618857264713,\n", + " 1608179136707,\n", + " 1608150154053,\n", + " 1519597518656,\n", + " 1576628542044,\n", + " 1597193878458,\n", + " 1473363029000,\n", + " 1410982930000,\n", + " 1619999304729,\n", + " 1616002109137,\n", + " 1578199450059,\n", + " 1606567678957,\n", + " 1600981489627,\n", + " 1600608861312,\n", + " 1599831207548,\n", + " 1590776980036,\n", + " 1573364776103,\n", + " 1572059993754,\n", + " 1568738284832,\n", + " 1489507732000,\n", + " 1505387218171,\n", + " 1581460885276,\n", + " 1568925995715,\n", + " 1486999572000,\n", + " 1420074541000,\n", + " 1261767824000,\n", + " 1541511894439,\n", + " 1541511735430,\n", + " 1587093908228,\n", + " 1678571121367,\n", + " 1661749238153,\n", + " 1659768543856,\n", + " 1654910784744,\n", + " 1633138052769,\n", + " 1630609578211,\n", + " 1630284777853,\n", + " 1621575250672,\n", + " 1620932469461,\n", + " 1612994678917,\n", + " 1611551927699,\n", + " 1611548309557,\n", + " 1610787779228,\n", + " 1610765636781,\n", + " 1607202914733,\n", + " 1606338770516,\n", + " 1605613110667,\n", + " 1603740124160,\n", + " 1601706559533,\n", + " 1601115486588,\n", + " 1599947601009,\n", + " 1594722816304,\n", + " 1594613631750,\n", + " 1594605653363,\n", + " 1672923265267,\n", + " 1661250552056,\n", + " 1581179990454,\n", + " 1636215354772,\n", + " 1669050392120,\n", + " 1657435246796,\n", + " 1618821944944,\n", + " 1614913693947,\n", + " 1614908720232,\n", + " 1612490745122,\n", + " 1611025705067,\n", + " 1373625451000,\n", + " 1580200590579,\n", + " 1639345897619,\n", + " 1495547055000,\n", + " 1466003749000,\n", + " 1641946135758,\n", + " 1470738729000,\n", + " 1504796875401,\n", + " 1481912567000,\n", + " 1461478317000,\n", + " 1411776623000,\n", + " 1597699676534,\n", + " 1592165525809,\n", + " 1610755123373,\n", + " 1353794687000,\n", + " 1619028441413,\n", + " 1536792279960,\n", + " 1555098464297,\n", + " 1529964433471,\n", + " 1439143316000,\n", + " 1554106521639,\n", + " 1475443663000,\n", + " 1488722567000,\n", + " 1462490224000,\n", + " 1584146451888,\n", + " 1641345477204,\n", + " 1562614382993,\n", + " 1466436690000,\n", + " 1655006259749,\n", + " 1542419324723,\n", + " 1444583404000,\n", + " 1647073799344,\n", + " 1614000161505,\n", + " 1629007196471,\n", + " 1619550188658,\n", + " 1422820591000,\n", + " 1639081363113,\n", + " 1617240878661,\n", + " 1591520447864,\n", + " 1592924276710,\n", + " 1462511233000,\n", + " 1536796053895,\n", + " 1582906066647,\n", + " 1582904960575,\n", + " 1458938351000,\n", + " 1639773425904,\n", + " 1583435029909,\n", + " 1539862221695,\n", + " 1629588099167,\n", + " 1605475813779,\n", + " 1605475740207,\n", + " 1447361356000,\n", + " 1511765649527,\n", + " 1654279974836,\n", + " 1564242744672,\n", + " 1452100737000,\n", + " 1423594201000,\n", + " 1577896005378,\n", + " 1530032340110,\n", + " 1530032269668,\n", + " 1625076116513,\n", + " 1600589911375,\n", + " 1554215163334,\n", + " 1627309847298,\n", + " 1583793386633,\n", + " 1583793293537,\n", + " 1582420764008,\n", + " 1640574278183,\n", + " 1628273687997,\n", + " 1493572785000,\n", + " 1676202555202,\n", + " 1676485728534,\n", + " 1653188721784,\n", + " 1652553785424,\n", + " 1647797592438,\n", + " 1643236108740,\n", + " 1635374032961,\n", + " 1624310047769,\n", + " 1613517065927,\n", + " 1638708824621,\n", + " 1511201711098,\n", + " 1634503131361,\n", + " 1574980368028,\n", + " 1532886092264,\n", + " 1655377333106,\n", + " 1537623163271,\n", + " 1560317016306,\n", + " 1509069747227,\n", + " 1674344999421,\n", + " 1555529047011,\n", + " 1581650941564,\n", + " 1666187217742,\n", + " 1569513529747,\n", + " 1596130734355,\n", + " 1656606091183,\n", + " 1146326778000,\n", + " 1359821543000,\n", + " 1528164314147,\n", + " 1515732177290,\n", + " 1509422238752,\n", + " 1501261657025,\n", + " 1468867203000,\n", + " 1517609876896,\n", + " 1450891988000,\n", + " 1567909215439,\n", + " 1650748965011,\n", + " 1645323794674,\n", + " 1592844951873,\n", + " 1615012826059,\n", + " 1581758635824,\n", + " 1571728673127,\n", + " 1555821397948,\n", + " 1539161656765,\n", + " 1520787389970,\n", + " 1497532687670,\n", + " 1487467574000,\n", + " 1494690822000,\n", + " 1667036913218,\n", + " 1439161846000,\n", + " 1529060993932,\n", + " 1600645520822,\n", + " 1521017740537,\n", + " 1573747147837,\n", + " 1484270671000,\n", + " 1466476209000,\n", + " 1641425188730,\n", + " 1628030283862,\n", + " 1515636693590,\n", + " 1459813617000,\n", + " 1470070653000,\n", + " 1479530168000,\n", + " 1424640438000,\n", + " 1448687889000,\n", + " 1480129396000,\n", + " 1485145644000,\n", + " 1485482265000,\n", + " 1471794447000,\n", + " 1575084706632,\n", + " 1477432087000,\n", + " 1574012622203,\n", + " 1615684014760,\n", + " 1500045846496,\n", + " 1516986917026,\n", + " 1514996428571,\n", + " 1603791051640,\n", + " 1534302521898,\n", + " 1442937927000,\n", + " 1649267994257,\n", + " 1596413259492,\n", + " 1553381457370,\n", + " 1541790790117,\n", + " 1650759543649,\n", + " 1676311452919,\n", + " 1501304037469,\n", + " 1501302098787,\n", + " 1483565714000,\n", + " 1483565692000,\n", + " 1539553427884,\n", + " 1627578372372,\n", + " 1578535070782,\n", + " 1644008116042,\n", + " 1614192177129,\n", + " 1647970066495,\n", + " 1648942945279,\n", + " 1642813802501,\n", + " 1477119472000,\n", + " 1572822001137,\n", + " 1550759240757,\n", + " 1549308298117,\n", + " 1606272320691,\n", + " 1658103977600,\n", + " 1631940463386,\n", + " 1592186597736,\n", + " 1590617223230,\n", + " 1623269307538,\n", + " 1637952741170,\n", + " 1637951918416,\n", + " 1595775105700,\n", + " 1593535704361,\n", + " 1474553894000,\n", + " 1502510924018,\n", + " 1626791400140,\n", + " 1614555505613,\n", + " 1616094700987,\n", + " 1500572336747,\n", + " 1615829629280,\n", + " 1512454755912,\n", + " 1616279310856,\n", + " 1472178609000,\n", + " 1560092752091,\n", + " 1552095858684,\n", + " 1589037099472,\n", + " 1631567504597,\n", + " 1625920561591,\n", + " 1574883290283,\n", + " 1588833031713,\n", + " 1596132271452,\n", + " 1626662080741,\n", + " 1389986319000,\n", + " 1197914295000,\n", + " 1647553520139,\n", + " 1600745243711,\n", + " 1597092507038,\n", + " 1506752237093,\n", + " 1474460530000,\n", + " 1576645128712,\n", + " 1281983258000,\n", + " 1523832685129,\n", + " 1558221875804,\n", + " 1556631320017,\n", + " 1628634922374,\n", + " 1627667180191,\n", + " 1601834280664,\n", + " 1597094560252,\n", + " 1592282719196,\n", + " 1586229467743,\n", + " 1574142848734,\n", + " 1538586113610,\n", + " 1448734780000,\n", + " 1434130419000,\n", + " 1443564925000,\n", + " 1627259395891,\n", + " 1653936169380,\n", + " 1627318635317,\n", + " 1618532347712,\n", + " 1608184432478,\n", + " 1605285789964,\n", + " 1541430363499,\n", + " 1667020920714,\n", + " 1653758012609,\n", + " 1504198444887,\n", + " 1422641622000,\n", + " 1602002157872,\n", + " 1497149781843,\n", + " 1563731102200,\n", + " 1584370941684,\n", + " 1623808858207,\n", + " 1635262621710,\n", + " 1546985585251,\n", + " 1630381742965,\n", + " 1558562589257,\n", + " 1645642995446,\n", + " 1455998705000,\n", + " 1582413056586,\n", + " 1676291863298,\n", + " 1638355385224,\n", + " 1566639539440,\n", + " 1543379247659,\n", + " 1542096238469,\n", + " 1428326651000,\n", + " 1373270523000,\n", + " 1624191067930,\n", + " 1641828101630,\n", + " 1408016114000,\n", + " 1561994040711,\n", + " 1436758933000,\n", + " 1642874487486,\n", + " 1575258406339,\n", + " 1571790772101,\n", + " 1470690701000,\n", + " 1662843152558,\n", + " 1582652288223,\n", + " 1538752155966,\n", + " 1626662438992,\n", + " 1504980315283,\n", + " 1608397521591,\n", + " 1521145790281,\n", + " 1510428835488,\n", + " 1524252198455,\n", + " 1436564358000,\n", + " 1577727263975,\n", + " 1528771497436,\n", + " 1632849212320,\n", + " 1629812497455,\n", + " 1626705879323,\n", + " 1625843890463,\n", + " 1623860962101,\n", + " 1623515969971,\n", + " 1623425165592,\n", + " 1622908739665,\n", + " 1621265725765,\n", + " 1620487703457,\n", + " 1618246231408,\n", + " 1618154434194,\n", + " 1617996116596,\n", + " 1617976974722,\n", + " 1617647825323,\n", + " 1616268657427,\n", + " 1615396787027,\n", + " 1614785049927,\n", + " 1614619525190,\n", + " 1614614689120,\n", + " 1614302154167,\n", + " 1612643175027,\n", + " 1612277896403,\n", + " 1612199110264,\n", + " 1612111320590,\n", + " 1612028228543,\n", + " 1610819341130,\n", + " 1610729944227,\n", + " 1610155682447,\n", + " 1608561747997,\n", + " 1608313320919,\n", + " 1607908220469,\n", + " 1607700627887,\n", + " 1606514882493,\n", + " 1605882712736,\n", + " 1605626461999,\n", + " 1605285001466,\n", + " 1605277820525,\n", + " 1605189580741,\n", + " 1605188641151,\n", + " 1604887477422,\n", + " 1603653437313,\n", + " 1603474193808,\n", + " 1602256451928,\n", + " 1601744886228,\n", + " 1601348228292,\n", + " 1600623351306,\n", + " 1597756252489,\n", + " 1596938837662,\n", + " 1596160676248,\n", + " 1595442388136,\n", + " 1593570937241,\n", + " 1592427032313,\n", + " 1580061530082,\n", + " 1569875262983,\n", + " 1568909474636,\n", + " 1561224373116,\n", + " 1561140836683,\n", + " 1555785204360,\n", + " 1555438600776,\n", + " 1555270893135,\n", + " 1555083048699,\n", + " 1611861742012,\n", + " 1624109032559,\n", + " 1614358326453,\n", + " 1603283831576,\n", + " 1626718654894,\n", + " 1551793190957,\n", + " 1609003515607,\n", + " 1567458289413,\n", + " 1612843190957,\n", + " 1595697521926,\n", + " 1594134346120,\n", + " 1607784883967,\n", + " 1667573369550,\n", + " 1665248367834,\n", + " 1653950005938,\n", + " 1652208843777,\n", + " 1635465733717,\n", + " 1633574201681,\n", + " 1633574018057,\n", + " 1631811033570,\n", + " 1630781736770,\n", + " 1629320870245,\n", + " 1625929042684,\n", + " 1624808771458,\n", + " 1623110181984,\n", + " 1622500335898,\n", + " 1620956594275,\n", + " 1613435582439,\n", + " 1602445577202,\n", + " 1620119701896,\n", + " 1594761445436,\n", + " 1585365632965,\n", + " 1582808148231,\n", + " 1580129532108,\n", + " 1579093306899,\n", + " 1473442211000,\n", + " 1495165475000,\n", + " 1669216602355,\n", + " 1657982478280,\n", + " 1641966782109,\n", + " 1640644020361,\n", + " 1639856957547,\n", + " 1639853056274,\n", + " 1638555495503,\n", + " 1638479685636,\n", + " 1638141264181,\n", + " 1638065838310,\n", + " 1637804836491,\n", + " 1637200808637,\n", + " 1636855327654,\n", + " 1635738859991,\n", + " 1634259115164,\n", + " 1631820815569,\n", + " 1629931507170,\n", + " 1629218016977,\n", + " 1628899900187,\n", + " 1627956347688,\n", + " 1625711951056,\n", + " 1623949076043,\n", + " 1623633511549,\n", + " 1623033973756,\n", + " 1582417445493,\n", + " 1412647600000,\n", + " 1630225112831,\n", + " 1629190054802,\n", + " 1629012724009,\n", + " 1619867170385,\n", + " 1619865892493,\n", + " 1529729961124,\n", + " 1449970706000,\n", + " 1422137950000,\n", + " 1492540415000,\n", + " 1488945489000,\n", + " 1579880865265,\n", + " 1644091755933,\n", + " 1642739514660,\n", + " 1642739335845,\n", + " 1615082299387,\n", + " 1608505236549,\n", + " 1459903064000,\n", + " 1459897607000,\n", + " 1446509148000,\n", + " 1409249979000,\n", + " 1639987040377,\n", + " 1632723134917,\n", + " 1632478192625,\n", + " 1628910099825,\n", + " 1626349138206,\n", + " 1619168964723,\n", + " 1618738844280,\n", + " 1614125978911,\n", + " 1603750716714,\n", + " 1571930076040,\n", + " 1624382648359,\n", + " 1624342078041,\n", + " 1623449961393,\n", + " 1630868975188,\n", + " 1610831769055,\n", + " 1610206520556,\n", + " 1597266333567,\n", + " 1586595584020,\n", + " 1584189354507,\n", + " 1583773994689,\n", + " 1583543347297,\n", + " 1580258795459,\n", + " 1579811989015,\n", + " 1579377692730,\n", + " 1578874198465,\n", + " 1577489444033,\n", + " 1577466344815,\n", + " 1576841851794,\n", + " 1576668656590,\n", + " 1558875061235,\n", + " 1123589578000,\n", + " 1603766626713,\n", + " 1618673248487,\n", + " 1616632091857,\n", + " 1476168243000,\n", + " 1468884984000,\n", + " 1468812443000,\n", + " 1468034327000,\n", + " 1467323562000,\n", + " 1461122973000,\n", + " 1451111542000,\n", + " 1617130297134,\n", + " 1653418516337,\n", + " 1638706559186,\n", + " 1617888653841,\n", + " 1577108239073,\n", + " 1375358609000,\n", + " 1454675992000,\n", + " 1630111444588,\n", + " 1585438138801,\n", + " 1480369888000,\n", + " 1556814101678,\n", + " 1545067887121,\n", + " 1601994683341,\n", + " 1610377321297,\n", + " 1659918169411,\n", + " 1626888774973,\n", + " 1623016040784,\n", + " 1614390348005,\n", + " 1626908591516,\n", + " 1614543360900,\n", + " 1614543207191,\n", + " 1607766679738,\n", + " 1603885864456,\n", + " 1603024547462,\n", + " 1602361342066,\n", + " 1596972059141,\n", + " 1596361831112,\n", + " 1593636481145,\n", + " 1593178632696,\n", + " 1590237125367,\n", + " 1582833061122,\n", + " 1579468220080,\n", + " 1576950976082,\n", + " 1570467139954,\n", + " 1594658130157,\n", + " 1624810996022,\n", + " 1595521885393,\n", + " 1659097569261,\n", + " 1614638097256,\n", + " 1636063582513,\n", + " 1601325516368,\n", + " 1612026709081,\n", + " 1593218464870,\n", + " 1582267188322,\n", + " 1567606869144,\n", + " 1557102642721,\n", + " 1645538841735,\n", + " 1634752789948,\n", + " 1621074811741,\n", + " 1618333357402,\n", + " 1601462568570,\n", + " 1598100257381,\n", + " 1596124000250,\n", + " 1592649151279,\n", + " 1591874117611,\n", + " 1579256820590,\n", + " 1577153617349,\n", + " 1571877375094,\n", + " 1568510731475,\n", + " 1501268331369,\n", + " 1421531037000,\n", + " 1391711822000,\n", + " 1551402155184],\n", + " 'helpful_vote': [0,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 430,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 8,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 4,\n", + " 1,\n", + " 5,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 13,\n", + " 0,\n", + " 1,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 8,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 1,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 2,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 2,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 8,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 4,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 2,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 5,\n", + " 2,\n", + " 4,\n", + " 5,\n", + " 2,\n", + " 5,\n", + " 3,\n", + " 2,\n", + " 3,\n", + " 3,\n", + " 2,\n", + " 2,\n", + " 3,\n", + " 5,\n", + " 3,\n", + " 2,\n", + " 2,\n", + " 2,\n", + " 8,\n", + " 3,\n", + " 3,\n", + " 2,\n", + " 2,\n", + " 2,\n", + " 6,\n", + " 3,\n", + " 2,\n", + " 2,\n", + " 2,\n", + " 4,\n", + " 5,\n", + " 2,\n", + " 3,\n", + " 2,\n", + " 2,\n", + " 1,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 6,\n", + " 1,\n", + " 0,\n", + " 16,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 9,\n", + " 2,\n", + " 0,\n", + " 7,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 7,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 4,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 7,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 49,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 11,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 5,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 7,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 7,\n", + " 0,\n", + " 15,\n", + " 4,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 8,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 6,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 6,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 9,\n", + " 7,\n", + " 6,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 58,\n", + " 1,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 5,\n", + " 7,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 5,\n", + " 5,\n", + " 3,\n", + " 5,\n", + " 6,\n", + " 6,\n", + " 0,\n", + " 0,\n", + " 24,\n", + " 1,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 5,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 0,\n", + " 2,\n", + " 20,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 20,\n", + " 2,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 9,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 5,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 3,\n", + " 5,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 4,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 34,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 1,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 3,\n", + " 0,\n", + " 0,\n", + " 2,\n", + " 1,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0,\n", + " 0],\n", + " 'verified_purchase': [True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " True,\n", + " False,\n", + " True,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " False,\n", + " True,\n", + " True,\n", + " False,\n", + " True]}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ - "# Load Amazon Reviews dataset\n", - "from datasets import load_dataset\n", - "dataset = load_dataset(\"McAuley-Lab/Amazon-Reviews-2023\", \"raw_review_All_Beauty\", trust_remote_code=True)" + "reviews" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -142,7 +11732,7 @@ ")" ] }, - "execution_count": 3, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -162,47 +11752,68 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "LlamaForCausalLM(\n", - " (model): LlamaModel(\n", - " (embed_tokens): Embedding(49152, 576)\n", - " (layers): ModuleList(\n", - " (0-29): 30 x LlamaDecoderLayer(\n", - " (self_attn): LlamaAttention(\n", - " (q_proj): Linear(in_features=576, out_features=576, bias=False)\n", - " (k_proj): Linear(in_features=576, out_features=192, bias=False)\n", - " (v_proj): Linear(in_features=576, out_features=192, bias=False)\n", - " (o_proj): Linear(in_features=576, out_features=576, bias=False)\n", - " )\n", - " (mlp): LlamaMLP(\n", - " (gate_proj): Linear(in_features=576, out_features=1536, bias=False)\n", - " (up_proj): Linear(in_features=576, out_features=1536, bias=False)\n", - " (down_proj): Linear(in_features=1536, out_features=576, bias=False)\n", - " (act_fn): SiLU()\n", - " )\n", - " (input_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", - " (post_attention_layernorm): LlamaRMSNorm((576,), eps=1e-05)\n", - " )\n", - " )\n", - " (norm): LlamaRMSNorm((576,), eps=1e-05)\n", - " (rotary_emb): LlamaRotaryEmbedding()\n", - " )\n", - " (lm_head): Linear(in_features=576, out_features=49152, bias=False)\n", - ")" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" + "ename": "ValueError", + "evalue": "text input must be of type `str` (single example), `List[str]` (batch or single pretokenized example) or `List[List[str]]` (batch of pretokenized examples).", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[10], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# 3. Tokenize the reviews with padding for batch processing\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m encodings \u001b[38;5;241m=\u001b[39m \u001b[43mtokenizer\u001b[49m\u001b[43m(\u001b[49m\u001b[43mreviews\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mreturn_tensors\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpt\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpadding\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtruncation\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[0;32m 3\u001b[0m input_ids \u001b[38;5;241m=\u001b[39m encodings[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124minput_ids\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mto(device)\n\u001b[0;32m 4\u001b[0m attention_mask \u001b[38;5;241m=\u001b[39m encodings[\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mattention_mask\u001b[39m\u001b[38;5;124m'\u001b[39m]\u001b[38;5;241m.\u001b[39mto(device)\n", + "File \u001b[1;32mc:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\transformers\\tokenization_utils_base.py:2868\u001b[0m, in \u001b[0;36mPreTrainedTokenizerBase.__call__\u001b[1;34m(self, text, text_pair, text_target, text_pair_target, add_special_tokens, padding, truncation, max_length, stride, is_split_into_words, pad_to_multiple_of, padding_side, return_tensors, return_token_type_ids, return_attention_mask, return_overflowing_tokens, return_special_tokens_mask, return_offsets_mapping, return_length, verbose, **kwargs)\u001b[0m\n\u001b[0;32m 2866\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_in_target_context_manager:\n\u001b[0;32m 2867\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_switch_to_input_mode()\n\u001b[1;32m-> 2868\u001b[0m encodings \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call_one\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtext\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtext\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtext_pair\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtext_pair\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mall_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 2869\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m text_target \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 2870\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_switch_to_target_mode()\n", + "File \u001b[1;32mc:\\Users\\chand\\miniconda3\\envs\\torchleet\\Lib\\site-packages\\transformers\\tokenization_utils_base.py:2928\u001b[0m, in \u001b[0;36mPreTrainedTokenizerBase._call_one\u001b[1;34m(self, text, text_pair, add_special_tokens, padding, truncation, max_length, stride, is_split_into_words, pad_to_multiple_of, padding_side, return_tensors, return_token_type_ids, return_attention_mask, return_overflowing_tokens, return_special_tokens_mask, return_offsets_mapping, return_length, verbose, split_special_tokens, **kwargs)\u001b[0m\n\u001b[0;32m 2925\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[0;32m 2927\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _is_valid_text_input(text):\n\u001b[1;32m-> 2928\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 2929\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtext input must be of type `str` (single example), `List[str]` (batch or single pretokenized example) \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 2930\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mor `List[List[str]]` (batch of pretokenized examples).\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 2931\u001b[0m )\n\u001b[0;32m 2933\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m text_pair \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _is_valid_text_input(text_pair):\n\u001b[0;32m 2934\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[0;32m 2935\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtext input must be of type `str` (single example), `List[str]` (batch or single pretokenized example) \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 2936\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mor `List[List[str]]` (batch of pretokenized examples).\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 2937\u001b[0m )\n", + "\u001b[1;31mValueError\u001b[0m: text input must be of type `str` (single example), `List[str]` (batch or single pretokenized example) or `List[List[str]]` (batch of pretokenized examples)." + ] } ], "source": [ - "model" + "# 3. Tokenize the reviews with padding for batch processing\n", + "encodings = tokenizer(reviews, return_tensors=\"pt\", padding=True, truncation=True)\n", + "input_ids = encodings['input_ids'].to(device)\n", + "attention_mask = encodings['attention_mask'].to(device)\n", + "\n", + "# 4. Forward pass with output_hidden_states=True to get all hidden states\n", + "with torch.no_grad():\n", + " outputs = model(input_ids, attention_mask=attention_mask, output_hidden_states=True)\n", + "\n", + "# 5. Extract last hidden states (batch_size, seq_len, hidden_dim)\n", + "last_hidden_states = outputs.hidden_states[-1]\n", + "\n", + "# 6. Compute sentence embeddings by averaging token embeddings excluding padding tokens\n", + "# attention_mask has 1 for real tokens, 0 for padding\n", + "expanded_mask = attention_mask.unsqueeze(-1).expand(last_hidden_states.size()).float() # (batch, seq_len, hidden_dim)\n", + "sum_embeddings = torch.sum(last_hidden_states * expanded_mask, dim=1)\n", + "sum_mask = torch.clamp(expanded_mask.sum(dim=1), min=1e-9) # avoid division by zero\n", + "sentence_embeddings = sum_embeddings / sum_mask # (batch_size, hidden_dim)\n", + "\n", + "print(\"Sentence embeddings shape:\", sentence_embeddings.shape) # (10, hidden_dim)\n", + "\n", + "# --- Cosine similarity for a given keyword ---\n", + "\n", + "# Example keyword\n", + "keyword = \"quality\"\n", + "\n", + "# Tokenize and embed the keyword the same way\n", + "keyword_enc = tokenizer(keyword, return_tensors=\"pt\")\n", + "keyword_input_ids = keyword_enc['input_ids'].to(device)\n", + "keyword_attention_mask = keyword_enc['attention_mask'].to(device)\n", + "\n", + "with torch.no_grad():\n", + " keyword_outputs = model(keyword_input_ids, attention_mask=keyword_attention_mask, output_hidden_states=True)\n", + "\n", + "keyword_last_hidden = keyword_outputs.hidden_states[-1]\n", + "keyword_mask = keyword_attention_mask.unsqueeze(-1).expand(keyword_last_hidden.size()).float()\n", + "keyword_embedding = (keyword_last_hidden * keyword_mask).sum(dim=1) / torch.clamp(keyword_mask.sum(dim=1), min=1e-9)\n", + "\n", + "# Compute cosine similarity between keyword embedding and each review embedding\n", + "cosine_similarities = F.cosine_similarity(sentence_embeddings, keyword_embedding)\n", + "\n", + "for i, (review, sim) in enumerate(zip(reviews, cosine_similarities)):\n", + " print(f\"\\nReview #{i+1} similarity to '{keyword}': {sim.item():.4f}\")\n", + " print(review)" ] } ], From b0275e270a6c3bb1e38060c26254c644c5ec6d64 Mon Sep 17 00:00:00 2001 From: Chandrahas Aroori Date: Sat, 31 May 2025 10:17:14 -0700 Subject: [PATCH 39/40] Clean up --- ...PE-q3-Question.ipynb => BPE-q3-SOLN.ipynb} | 35 ++++++++-- llm/Byte-Pair-Encoder/BPE-q3.ipynb | 35 ++-------- .../attention-q4-Question.ipynb | 64 ++++++++++++++----- .../attention-q4.ipynb | 22 +++---- llm/RMS-Norm/rms-norm.ipynb | 47 ++++++++++++++ 5 files changed, 138 insertions(+), 65 deletions(-) rename llm/Byte-Pair-Encoder/{BPE-q3-Question.ipynb => BPE-q3-SOLN.ipynb} (78%) create mode 100644 llm/RMS-Norm/rms-norm.ipynb diff --git a/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb b/llm/Byte-Pair-Encoder/BPE-q3-SOLN.ipynb similarity index 78% rename from llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb rename to llm/Byte-Pair-Encoder/BPE-q3-SOLN.ipynb index ac089d0..ce3d058 100644 --- a/llm/Byte-Pair-Encoder/BPE-q3-Question.ipynb +++ b/llm/Byte-Pair-Encoder/BPE-q3-SOLN.ipynb @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "081a9dd1", "metadata": {}, "source": [ "## Problem: Write a Byte Pain Encoder in Python\n", @@ -33,6 +34,7 @@ { "cell_type": "code", "execution_count": null, + "id": "89f09999", "metadata": {}, "outputs": [], "source": [ @@ -40,22 +42,44 @@ "\n", "def get_vocab(corpus):\n", " \"\"\"Creates a vocabulary with words split into characters and a special end-of-word token.\"\"\"\n", - " ...\n", + " vocab = Counter()\n", + " for word in corpus:\n", + " tokens = list(word) + ['']\n", + " vocab[tuple(tokens)] += 1\n", " return vocab\n", "\n", "def get_stats(vocab):\n", " \"\"\"Counts frequency of adjacent symbol pairs.\"\"\"\n", - " ...\n", + " pairs = defaultdict(int)\n", + " for word, freq in vocab.items():\n", + " for i in range(len(word) - 1):\n", + " pairs[(word[i], word[i + 1])] += freq\n", " return pairs\n", "\n", "def merge_vocab(pair, vocab):\n", " \"\"\"Merges the most frequent pair into a single symbol.\"\"\"\n", - " ...\n", + " new_vocab = {}\n", + " bigram = ' '.join(pair)\n", + " replacement = ''.join(pair)\n", + " for word, freq in vocab.items():\n", + " word_str = ' '.join(word)\n", + " # Replace bigram with merged symbol\n", + " new_word_str = word_str.replace(bigram, replacement)\n", + " new_vocab[tuple(new_word_str.split())] = freq\n", " return new_vocab\n", "\n", "def byte_pair_encoding(corpus, num_merges=10):\n", " \"\"\"Performs BPE on a corpus.\"\"\"\n", - " ...\n", + " vocab = get_vocab(corpus)\n", + " merges = []\n", + " for _ in range(num_merges):\n", + " pairs = get_stats(vocab)\n", + " if not pairs:\n", + " break\n", + " best = max(pairs, key=pairs.get)\n", + " vocab = merge_vocab(best, vocab)\n", + " merges.append(best)\n", + " print(f\"Merge {_ + 1}: {best}\")\n", " return vocab, merges\n", "\n", "# Example usage\n", @@ -70,6 +94,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9e4638a1", "metadata": {}, "outputs": [], "source": [ @@ -118,5 +143,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 5 } diff --git a/llm/Byte-Pair-Encoder/BPE-q3.ipynb b/llm/Byte-Pair-Encoder/BPE-q3.ipynb index ce3d058..ac089d0 100644 --- a/llm/Byte-Pair-Encoder/BPE-q3.ipynb +++ b/llm/Byte-Pair-Encoder/BPE-q3.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "id": "081a9dd1", "metadata": {}, "source": [ "## Problem: Write a Byte Pain Encoder in Python\n", @@ -34,7 +33,6 @@ { "cell_type": "code", "execution_count": null, - "id": "89f09999", "metadata": {}, "outputs": [], "source": [ @@ -42,44 +40,22 @@ "\n", "def get_vocab(corpus):\n", " \"\"\"Creates a vocabulary with words split into characters and a special end-of-word token.\"\"\"\n", - " vocab = Counter()\n", - " for word in corpus:\n", - " tokens = list(word) + ['']\n", - " vocab[tuple(tokens)] += 1\n", + " ...\n", " return vocab\n", "\n", "def get_stats(vocab):\n", " \"\"\"Counts frequency of adjacent symbol pairs.\"\"\"\n", - " pairs = defaultdict(int)\n", - " for word, freq in vocab.items():\n", - " for i in range(len(word) - 1):\n", - " pairs[(word[i], word[i + 1])] += freq\n", + " ...\n", " return pairs\n", "\n", "def merge_vocab(pair, vocab):\n", " \"\"\"Merges the most frequent pair into a single symbol.\"\"\"\n", - " new_vocab = {}\n", - " bigram = ' '.join(pair)\n", - " replacement = ''.join(pair)\n", - " for word, freq in vocab.items():\n", - " word_str = ' '.join(word)\n", - " # Replace bigram with merged symbol\n", - " new_word_str = word_str.replace(bigram, replacement)\n", - " new_vocab[tuple(new_word_str.split())] = freq\n", + " ...\n", " return new_vocab\n", "\n", "def byte_pair_encoding(corpus, num_merges=10):\n", " \"\"\"Performs BPE on a corpus.\"\"\"\n", - " vocab = get_vocab(corpus)\n", - " merges = []\n", - " for _ in range(num_merges):\n", - " pairs = get_stats(vocab)\n", - " if not pairs:\n", - " break\n", - " best = max(pairs, key=pairs.get)\n", - " vocab = merge_vocab(best, vocab)\n", - " merges.append(best)\n", - " print(f\"Merge {_ + 1}: {best}\")\n", + " ...\n", " return vocab, merges\n", "\n", "# Example usage\n", @@ -94,7 +70,6 @@ { "cell_type": "code", "execution_count": null, - "id": "9e4638a1", "metadata": {}, "outputs": [], "source": [ @@ -143,5 +118,5 @@ } }, "nbformat": 4, - "nbformat_minor": 5 + "nbformat_minor": 2 } diff --git a/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb index 33ddcb1..cd65eb4 100644 --- a/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb +++ b/llm/Implement-Attention-from-Scratch/attention-q4-Question.ipynb @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -53,23 +53,27 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([1, 3, 3])\n" + ] + } + ], "source": [ - "# Synthetic data\n", - "torch.manual_seed(42)\n", - "q = torch.tensor([[[1.0, 0.5, 0.2], # Query for token 1\n", - " [0.3, 1.2, 0.7], # Query for token 2\n", - " [0.8, 0.1, 1.5]]]) # Query for token 3\n", + "import torch\n", "\n", - "k = torch.tensor([[[1.0, 0.2, 0.3], # Key for token 1\n", - " [0.4, 1.5, 0.6], # Key for token 2\n", - " [0.7, 0.1, 1.8]]]) # Key for token 3\n", + "torch.manual_seed(42)\n", "\n", - "v = torch.tensor([[[10.0, 2.0, 3.0], # Value for token 1\n", - " [4.0, 15.0, 6.0], # Value for token 2\n", - " [7.0, 1.0, 18.0]]]) # Value for token 3\n", + "batch_size = 1\n", + "seq_len = 3\n", + "dim = 3\n", "\n", - "print(q.shape)" + "q = torch.randn(batch_size, seq_len, dim)\n", + "k = torch.randn(batch_size, seq_len, dim)\n", + "v = torch.randn(batch_size, seq_len, dim)" ] }, { @@ -97,9 +101,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "ename": "TypeError", + "evalue": "cannot unpack non-iterable NoneType object", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[4], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m# Testing on data & compare\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m output_custom, _ \u001b[38;5;241m=\u001b[39m scaled_dot_product_attention(q, k, v)\n\u001b[0;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(output_custom)\n\u001b[0;32m 4\u001b[0m output \u001b[38;5;241m=\u001b[39m F\u001b[38;5;241m.\u001b[39mscaled_dot_product_attention(q, k, v)\n", + "\u001b[1;31mTypeError\u001b[0m: cannot unpack non-iterable NoneType object" + ] + } + ], "source": [ "# Testing on data & compare\n", "output_custom, _ = scaled_dot_product_attention(q, k, v)\n", @@ -112,8 +128,22 @@ } ], "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.9" } }, "nbformat": 4, diff --git a/llm/Implement-Attention-from-Scratch/attention-q4.ipynb b/llm/Implement-Attention-from-Scratch/attention-q4.ipynb index 11cbe2a..a98ceff 100644 --- a/llm/Implement-Attention-from-Scratch/attention-q4.ipynb +++ b/llm/Implement-Attention-from-Scratch/attention-q4.ipynb @@ -51,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -63,21 +63,17 @@ } ], "source": [ - "# Synthetic data\n", - "torch.manual_seed(42)\n", - "q = torch.tensor([[[1.0, 0.5, 0.2], # Query for token 1\n", - " [0.3, 1.2, 0.7], # Query for token 2\n", - " [0.8, 0.1, 1.5]]]) # Query for token 3\n", + "import torch\n", "\n", - "k = torch.tensor([[[1.0, 0.2, 0.3], # Key for token 1\n", - " [0.4, 1.5, 0.6], # Key for token 2\n", - " [0.7, 0.1, 1.8]]]) # Key for token 3\n", + "torch.manual_seed(42)\n", "\n", - "v = torch.tensor([[[10.0, 2.0, 3.0], # Value for token 1\n", - " [4.0, 15.0, 6.0], # Value for token 2\n", - " [7.0, 1.0, 18.0]]]) # Value for token 3\n", + "batch_size = 1\n", + "seq_len = 3\n", + "dim = 3\n", "\n", - "print(q.shape)" + "q = torch.randn(batch_size, seq_len, dim)\n", + "k = torch.randn(batch_size, seq_len, dim)\n", + "v = torch.randn(batch_size, seq_len, dim)" ] }, { diff --git a/llm/RMS-Norm/rms-norm.ipynb b/llm/RMS-Norm/rms-norm.ipynb new file mode 100644 index 0000000..38e74d3 --- /dev/null +++ b/llm/RMS-Norm/rms-norm.ipynb @@ -0,0 +1,47 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "ba5692f6", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "\n", + "class RMSNorm(nn.Module):\n", + " def __init__(self, dim: int, eps: float = 1e-8):\n", + " super().__init__()\n", + " self.eps = eps\n", + " self.scale = nn.Parameter(torch.ones(dim)) # gamma\n", + "\n", + " def forward(self, x: torch.Tensor) -> torch.Tensor:\n", + " # x: shape (..., dim)\n", + " norm = torch.sqrt(x.pow(2).mean(dim=-1, keepdim=True) + self.eps) # RMS\n", + " return (x / norm) * self.scale\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5813413b", + "metadata": {}, + "outputs": [], + "source": [ + "x = torch.randn(3, 5) # e.g., (batch_size=3, features=5)\n", + "rmsnorm = RMSNorm(dim=5)\n", + "out = rmsnorm(x)\n", + "print(out.shape) # should be (3, 5)\n", + "assert out.shape == (3, 5), \"Output shape mismatch\"" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From d2481a4e5269f39c4d4c71eb6b138b6882cfb606 Mon Sep 17 00:00:00 2001 From: bargav Date: Fri, 6 Jun 2025 15:08:08 -0400 Subject: [PATCH 40/40] added flash attention forward --- llm/flash-attention.ipynb | 1 + 1 file changed, 1 insertion(+) create mode 100644 llm/flash-attention.ipynb diff --git a/llm/flash-attention.ipynb b/llm/flash-attention.ipynb new file mode 100644 index 0000000..a77bc94 --- /dev/null +++ b/llm/flash-attention.ipynb @@ -0,0 +1 @@ +{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Flash Attention Forward Kernel Implementation\n\n### Task\n\nImplement a **Flash Attention (v2) Forward kernel** using Triton. Your kernel should take the following inputs:\n\n- `Q` (Query)\n- `K` (Key)\n- `V` (Value)\n\nAnd produce the following outputs:\n\n- `O` (Output)\n- `L` (Logsumexp values)\n\n### Requirements\n\n- Your Triton kernel must be launched with a grid configuration of **`(T_q, batch_size)`**, where:\n - Each Triton program instance handles **one tile of the `Q` tensor**,\n - and accesses data for a **single batch index**.\n\n- Within each program instance:\n - Load only the relevant tile from `Q`, and the corresponding batch slice from `K` and `V`,\n - Compute the attention scores and apply softmax using the logsumexp trick,\n - Store the result in the appropriate section of the output tensor `O`,\n - Store the logsumexp values in tensor `L`.\n\n### Notes\n\n- We will test with powers of 2 and at least 16, so you donโ€™t need to worry about\nout-of-bounds accesses.\n","metadata":{}},{"cell_type":"code","source":"import torch\nimport triton\nimport triton.language as tl\nimport math\n\n@triton.jit\ndef flash_fwd_kernel(Q_ptr, K_ptr, V_ptr, \n O_ptr, L_ptr,\n stride_qb, stride_qq, stride_qd,\n stride_kb, stride_kk, stride_kd,\n stride_vb, stride_vk, stride_vd,\n stride_ob, stride_ok, stride_od,\n stride_lb, stride_lq,\n N_q, N_k,\n scale,\n D: tl.constexpr,\n BLOCK_SIZE_Q: tl.constexpr,\n BLOCK_SIZE_K: tl.constexpr):\n \n # Program Indices\n query_tile_index = tl.program_id(0)\n batch_index = tl.program_id(1)\n\n # Block pointers\n Q_block_ptr = tl.make_block_ptr(Q_ptr + batch_index * stride_qb,\n shape=(N_q, D),\n strides=(stride_qq, stride_qd),\n offsets=(query_tile_index * BLOCK_SIZE_Q, 0),\n block_shape=(BLOCK_SIZE_Q, D),\n order=(1,0))\n ####### Your Code goes here ############\n \n pass\n ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Solution","metadata":{}},{"cell_type":"code","source":"import torch\nimport triton\nimport triton.language as tl\nimport math\n\n\n@triton.jit\ndef flash_fwd_kernel(Q_ptr, K_ptr, V_ptr, \n O_ptr, L_ptr,\n stride_qb, stride_qq, stride_qd,\n stride_kb, stride_kk, stride_kd,\n stride_vb, stride_vk, stride_vd,\n stride_ob, stride_ok, stride_od,\n stride_lb, stride_lq,\n N_q, N_k,\n scale,\n D: tl.constexpr,\n BLOCK_SIZE_Q: tl.constexpr,\n BLOCK_SIZE_K: tl.constexpr):\n \n # Program Indices\n query_tile_index = tl.program_id(0)\n batch_index = tl.program_id(1)\n\n # Block pointers\n Q_block_ptr = tl.make_block_ptr(Q_ptr + batch_index * stride_qb,\n shape=(N_q, D),\n strides=(stride_qq, stride_qd),\n offsets=(query_tile_index * BLOCK_SIZE_Q, 0),\n block_shape=(BLOCK_SIZE_Q, D),\n order=(1,0))\n \n K_block_ptr = tl.make_block_ptr(K_ptr + batch_index * stride_kb,\n shape=(D, N_k),\n strides=(stride_kd, stride_kk),\n offsets=(0, 0),\n block_shape=(D, BLOCK_SIZE_K),\n order=(0,1)) # Note: K is transposed in the kernel\n \n V_block_ptr = tl.make_block_ptr(V_ptr + batch_index * stride_vb,\n shape=(N_k, D),\n strides=(stride_vk, stride_vd),\n offsets=(0, 0),\n block_shape=(BLOCK_SIZE_K, D),\n order=(1,0))\n \n O_block_ptr = tl.make_block_ptr(O_ptr + batch_index * stride_ob,\n shape=(N_q, D),\n strides=(stride_ok, stride_od),\n offsets=(query_tile_index * BLOCK_SIZE_Q, 0),\n block_shape=(BLOCK_SIZE_Q, D),\n order=(1,0))\n \n L_block_ptr = tl.make_block_ptr(L_ptr + batch_index * stride_lb,\n shape=(N_q,),\n strides=(stride_lq,),\n offsets=(query_tile_index * BLOCK_SIZE_Q,),\n block_shape=(BLOCK_SIZE_Q,),\n order=(0,))\n \n l = tl.zeros([BLOCK_SIZE_Q], dtype=tl.float32) + 1.0 # Initialize l to 1.0\n out = tl.zeros([BLOCK_SIZE_Q, D], dtype=tl.float32)\n\n prev_max = tl.zeros([BLOCK_SIZE_Q], dtype=tl.float32) - float('inf') # Initialize s_max to negative infinity\n\n # Load query\n q = tl.load(Q_block_ptr).to(tl.float32)\n\n for i in range(0, N_k, BLOCK_SIZE_K):\n\n # Load keys and values\n k = tl.load(K_block_ptr).to(tl.float32)\n v = tl.load(V_block_ptr).to(tl.float32)\n\n # Compute the attention scores\n s = tl.dot(q, k) * scale\n curr_max = tl.maximum(prev_max, tl.max(s, axis=1))\n p = tl.math.exp(s - curr_max[:, None])\n\n\n # Compute the output\n alpha = tl.math.exp(prev_max - curr_max)\n out = out * alpha[:, None] + tl.dot(p, v)\n\n # To store the logsumexp for backward pass\n curr_l = tl.sum(p, axis=1)\n l = l * alpha + curr_l\n\n prev_max = curr_max\n\n # Advance block pointers\n K_block_ptr = tl.advance(K_block_ptr, (0, BLOCK_SIZE_K))\n V_block_ptr = tl.advance(V_block_ptr, (BLOCK_SIZE_K, 0))\n\n out = out / l[:, None] # Normalize the output\n tl.store(O_block_ptr, out.to(O_ptr.dtype.element_ty))\n\n # Store the logsumexp\n log_l = prev_max + tl.log(l)\n tl.store(L_block_ptr, log_l.to(L_ptr.dtype.element_ty))\n\n ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-06T19:03:37.207225Z","iopub.execute_input":"2025-06-06T19:03:37.208005Z","iopub.status.idle":"2025-06-06T19:03:37.223005Z","shell.execute_reply.started":"2025-06-06T19:03:37.207975Z","shell.execute_reply":"2025-06-06T19:03:37.222284Z"}},"outputs":[],"execution_count":15},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## TESTS","metadata":{}},{"cell_type":"code","source":" \n# Define problem size\nB, N_q, N_k, D = 1, 64, 128, 256 # Batch size, query len, key len, hidden dim\nBLOCK_SIZE_Q = 16\nBLOCK_SIZE_K = 16\n\n# Initialize inputs\nQ = torch.randn((B, N_q, D), dtype=torch.float16, device='cuda')\nK = torch.randn((B, N_k, D), dtype=torch.float16, device='cuda')\nV = torch.randn((B, N_k, D), dtype=torch.float16, device='cuda')\n\n# Outputs\nO = torch.empty((B, N_q, D), dtype=torch.float16, device='cuda')\nL = torch.empty((B, N_q), dtype=torch.float32, device='cuda')\n\n# Compute strides\nstride_qb, stride_qq, stride_qd = Q.stride()\nstride_kb, stride_kk, stride_kd = K.stride()\nstride_vb, stride_vk, stride_vd = V.stride()\nstride_ob, stride_ok, stride_od = O.stride()\nstride_lb, stride_lq = L.stride()\n\n# Call Triton kernel\ngrid = (triton.cdiv(N_q, BLOCK_SIZE_Q), B)\n\nflash_fwd_kernel[grid](\n Q, K, V, O, L,\n stride_qb, stride_qq, stride_qd,\n stride_kb, stride_kk, stride_kd,\n stride_vb, stride_vk, stride_vd,\n stride_ob, stride_ok, stride_od,\n stride_lb, stride_lq,\n N_q, N_k,\n scale=1.0 / math.sqrt(D),\n D=D,\n BLOCK_SIZE_Q=BLOCK_SIZE_Q,\n BLOCK_SIZE_K=BLOCK_SIZE_K,\n)\n\n# Print result\nprint(\"Output O:\", O[0, :5]) # Print first 5 query results\nprint(\"Logsumexp L:\", L[0, :5])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T19:03:49.722693Z","iopub.execute_input":"2025-06-06T19:03:49.723399Z","iopub.status.idle":"2025-06-06T19:03:50.790921Z","shell.execute_reply.started":"2025-06-06T19:03:49.723376Z","shell.execute_reply":"2025-06-06T19:03:50.790068Z"}},"outputs":[{"name":"stdout","text":"Output O: tensor([[-0.0423, 0.0367, 0.0788, ..., 0.1219, -0.1204, 0.1300],\n [-0.0228, -0.0631, -0.1155, ..., 0.0247, 0.0787, 0.0546],\n [-0.0792, 0.0242, -0.0278, ..., 0.2046, 0.0991, 0.0636],\n [-0.0681, -0.2094, 0.0441, ..., 0.1156, -0.0679, 0.1702],\n [-0.0521, -0.1407, -0.1186, ..., 0.1582, 0.0699, -0.0427]],\n device='cuda:0', dtype=torch.float16)\nLogsumexp L: tensor([5.4945, 5.4222, 5.2435, 5.4245, 5.3262], device='cuda:0')\n","output_type":"stream"}],"execution_count":16},{"cell_type":"code","source":"# Doing the same operation using PyTorch matmul operations\nQ_ref = Q.to(torch.float32)\nK_ref = K.to(torch.float32)\nV_ref = V.to(torch.float32)\n\nscale = 1.0 / math.sqrt(D)\nscores = torch.matmul(Q_ref, K_ref.transpose(-2, -1)) * scale # (B, N_q, N_k)\nattn = torch.nn.functional.softmax(scores, dim=-1) # (B, N_q, N_k)\nO_ref = torch.matmul(attn, V_ref) # (B, N_q, D)\n\n# Comparing Both\n\n# Convert Triton output to float32 for comparison\nO_triton = O.to(torch.float32)\n\nprint(torch.allclose(O_triton, O_ref, atol=1e-1, rtol=1e-2)) # Should be True\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T19:05:23.841987Z","iopub.execute_input":"2025-06-06T19:05:23.842471Z","iopub.status.idle":"2025-06-06T19:05:23.849223Z","shell.execute_reply.started":"2025-06-06T19:05:23.842450Z","shell.execute_reply":"2025-06-06T19:05:23.848594Z"}},"outputs":[{"name":"stdout","text":"True\n","output_type":"stream"}],"execution_count":21},{"cell_type":"code","source":"L_ref = torch.log(torch.sum(torch.exp(scores - scores.max(dim=-1, keepdim=True).values), dim=-1)) + scores.max(dim=-1).values\nL_triton = L.to(torch.float32)\n\nprint(torch.allclose(L_triton, L_ref, atol=1e-1, rtol=1e-2)) # Should be True\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-06T19:05:59.357044Z","iopub.execute_input":"2025-06-06T19:05:59.357336Z","iopub.status.idle":"2025-06-06T19:05:59.363363Z","shell.execute_reply.started":"2025-06-06T19:05:59.357315Z","shell.execute_reply":"2025-06-06T19:05:59.362815Z"}},"outputs":[{"name":"stdout","text":"True\n","output_type":"stream"}],"execution_count":22},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]} \ No newline at end of file