How combine results from multiple models in Google Vertex AI? - google-ai-platform

I have multiple models in Google Vertex AI and I want to create an endpoint to serve my predictions.
I need to run aggregation algorithms, like the Voting algorithm on the output of my models.
I have not found any ways of using the models together so that I can run the voting algorithms on the results.
Do I have to create a new model, curl my existing models and then run my algorithms on the results?

There is no in-built provision to implement aggregation algorithms in Vertex AI. To curl results from the models then aggregate them, we would need to deploy all of them to individual endpoints. Instead, I would suggest the below method to deploy the models and the meta-model(aggregate model) to a single endpoint using custom containers for prediction. The custom container requirements can be found here.
You can load the model artifacts from GCS into a custom container. If the same set of models are used (i.e) the input models to the meta-model do not change, you can package them inside the container to reduce load time. Then, a custom HTTP logic can be used to return the aggregation output like so. This is a sample custom flask server logic.
def get_models_from_gcs():
## Pull the required model artifacts from GCS and load them here.
models = [model_1, model_2, model_3]
return models
def aggregate_predictions(predictions):
## Your aggregation algorithm here
return aggregated_result
#app.post(os.environ['AIP_PREDICT_ROUTE'])
async def predict(request: Request):
body = await request.json()
instances = body["instances"]
inputs = np.asarray(instances)
preprocessed_inputs = _preprocessor.preprocess(inputs)
models = get_models_from_gcs()
predictions = []
for model in models:
predictions.append(model.predict(preprocessed_inputs))
aggregated_result = aggregate_predictions(predictions)
return {"aggregated_predictions": aggregated_result}

Related

Training Google-Cloud-Automl Model on multiple datasets

I would like to train an automl model on gcp's vertex ai using multiple datasets. I would like to keep the datasets separate, since they come from different sources, want to train on them separately, etc. Is that possible? Or will I need to create a dataset containing both datasets? It looks like I can only select one dataset in the web UI.
It is possible via the Vertex AI API as long as your sources are in Google Cloud Storage, just provide a list of training data which are in JSON or CSV format that qualifies with the best practices for formatting of training data.
See code for creating and importing datasets. See documentation for code reference and further details.
from typing import List, Union
from google.cloud import aiplatform
def create_and_import_dataset_image_sample(
project: str,
location: str,
display_name: str,
src_uris: Union[str, List[str]], // example: ["gs://bucket/file1.csv", "gs://bucket/file2.csv"]
sync: bool = True,
):
aiplatform.init(project=project, location=location)
ds = aiplatform.ImageDataset.create(
display_name=display_name,
gcs_source=src_uris,
import_schema_uri=aiplatform.schema.dataset.ioformat.image.single_label_classification,
sync=sync,
)
ds.wait()
print(ds.display_name)
print(ds.resource_name)
return ds
NOTE: The links provided are for Vertex AI AutoML Image. If you access the links there are options for other AutoML products like Text, Tabular and Video.

Download pre-trained sentence-transformers model locally

I am using the SentenceTransformers library (here: https://pypi.org/project/sentence-transformers/#pretrained-models) for creating embeddings of sentences using the pre-trained model bert-base-nli-mean-tokens. I have an application that will be deployed to a device that does not have internet access. Here, it's already been answered, how to save the model Download pre-trained BERT model locally. Yet I'm stuck at loading the saved model from the locally saved path.
When I try to save the model using the above-mentioned technique, these are the output files:
('/bert-base-nli-mean-tokens/tokenizer_config.json',
'/bert-base-nli-mean-tokens/special_tokens_map.json',
'/bert-base-nli-mean-tokens/vocab.txt',
'/bert-base-nli-mean-tokens/added_tokens.json')
When I try to load it in the memory, using
tokenizer = AutoTokenizer.from_pretrained(to_save_path)
I'm getting
Can't load config for '/bert-base-nli-mean-tokens'. Make sure that:
- '/bert-base-nli-mean-tokens' is a correct model identifier listed on 'https://huggingface.co/models'
- or '/bert-base-nli-mean-tokens' is the correct path to a directory containing a config.json
You can download and load the model like this
from sentence_transformers import SentenceTransformer
modelPath = "local/path/to/model
model = SentenceTransformer('bert-base-nli-stsb-mean-tokens')
model.save(modelPath)
model = SentenceTransformer(modelPath)
this worked for me.You can check the SBERT documentation for model details for the SentenceTransformer class [Here][1]
[1]: https://www.sbert.net/docs/package_reference/SentenceTransformer.html#:~:text=class,Optional%5Bstr%5D%20%3D%20None)
There are many ways to solve this issue:
Assuming you have trained your BERT base model locally (colab/notebook), in order to use it with the Huggingface AutoClass, then the model (along with the tokenizers,vocab.txt,configs,special tokens and tf/pytorch weights) has to be uploaded to Huggingface. The steps to do this is mentioned here. Once it is uploaded, there will be a repository created with your username, and then the model can be accessed as follows:
from transformers import AutoTokenizer
from transformers import pipeline
tokenizer = AutoTokenizer.from_pretrained("<username>/<model-name>")
The second way is to use the trained model locally, and this can be done by using pipelines.The following is an example how to use this model trained(&saved) locally for your use-case (giving an example from my locally trained QA model):
from transformers import AutoModelForQuestionAnswering,AutoTokenizer,pipeline
nlp_QA=pipeline('question-answering',model='./abhilash1910/distilbert-squadv1',tokenizer='./abhilash1910/distilbert-squadv1')
QA_inp={
'question': 'What is the fund price of Huggingface in NYSE?',
'context': 'Huggingface Co. has a total fund price of $19.6 million dollars'
}
result=nlp_QA(QA_inp)
result
The third way is to directly use Sentence Transformers from the Huggingface models repo.
There are also other ways to resolve this but these might help. Also this list of pretrained models might help.

Reusing h2o model mojo or pojo file from python

As H2o models are only reusable with the same major version of h2o they were saved with, an alternative is to save the model as MOJO/POJO format. Is there a way these saved models can be reused/loaded from python code. Or is there any way to keep the model for further development when upgrading the H2O version??
If you want to use your model for scoring via python, you could use either h2o.mojo_predict_pandas or h2o.mojo_predict_csv. But otherwise if you want to load a binary model that you previously saved, you will need to have compatible versions.
Outside of H2O-3 you can look into pyjnius as Tom recommended: https://github.com/kivy/pyjnius
Another alternative is to use pysparkling, if you only need it for scoring:
from pysparkling.ml import H2OMOJOModel
# Load test data to predict
df = spark.read.parquet(test_data_path)
# Load mojo model
mojo = H2OMOJOModel.createFromMojo(mojo_path)
# Make predictions
predictions = mojo.transform(df)
# Show predictions with ground truth (y_true and y_pred)
predictions.select('your_target_column', 'prediction').show()

How to structure Shopify data into a Firestore collection that can be queried efficiently

The Background
In an attempt to build some back-end services for my e-commerce (Shopify based) site I have set up a Firestore trigger that writes order details with every new order created which is updated by a web hook POST function provided by Shopify - (orders/Create webhook).
My current cloud function -
exports.saveOrderDetails = functions.https.onRequest((req, res) => {
var docRef = db.collection('orders').doc(req.body.name);
const details = req.body;
var setData = docRef.set(req.body).then( a =>{
res.status(200).send();
});
});
Which is able to capture the data from the webhook and store it in the order number's "name" document within my "orders" collection. This is how it looks in Firestore:
My question is - with the help of body-parser (already parsing out "name" which is represented as #9999 in my screenshot, to set my document name value) - how could I improve my cloud function to handle storing this webhook POST in a better data structure for Firestore and to query it later?
After reviewing the comments on this question, I moved this question over to Firebase-Talk and it appears the feature I am attempting here would be close to what is known as "collection group queries" and was informed I should adjust my data model approach since this feature is currently still on the road map - and perhaps look into the Firestore REST API as suggested by #jason-berryman
Besides the REST APi, #frank-van-puffelen made a great suggestion to look into working with Arrays, Lists, Sets for Firebase/Firestore
Another approach that could mitigate this in my scenario is to have my HTTP Firestore cloud trigger have multiple parsing arguments that create top more top level documents - however this could cause a point of scaling failure or an increase of cost factor due to putting more parsing processing logic in my cloud function and adding additional latency...
I will mark my question as answered for the time being to hopefully help others to understand how to work with documents in a single collection in Firestore and not attempt to query groups of collections before they get too far into modelling and need to restructure their app.

Entity Framework--Filter Data At Load Time

I’m building an MVC3 application with form authentication and a single hierarchical entity. The entity has a Region object as the “root” with several other objects. It looks something like:
Region->Language->objectA->objectB
Region->Application->….
Each user (other than administrators) is associated with single region. I'd like to limit the data loaded to the entity based on the user’s region. I’m not too familiar with EF. Is this appropriate or is there a better approach? How would I implement the best approach
You can certainly filter the data returned via Entity Framework. The code would look something like this:
using (MyContext ctx = new MyContext())
{
var filtered = (from r in ctx.Regions where SOME_CONDITIONS select r);
// Do stuff with filtered (which is an IEnumerable<Region>)
}
Note that you may need to use Include to load related objects, e.g.
ctx.Regions.Include("Language").Include("Application")
see http://msdn.microsoft.com/en-us/library/bb896272.aspx

Resources